Compare commits

...

561 Commits

Author SHA1 Message Date
joaquintides b6a0722f11 documented incompatibility of safe mode with containers in shared memory (closes #95) 2026-06-27 20:25:10 +02:00
joaquintides fbeaf88056 extended fancy pointer support for iterators (#100)
* added memory relocatability test
* added missing #includes
* avoided C++14 std::make_unique
* added hashed index local iterators to the test
* made all iterators store allocator-provided pointers to the nodes
* updated docs
2026-06-27 19:41:10 +02:00
joaquintides 19237f650a allowed deprecated node 20 (#99)
* updated to actions/checkout@v5
* reverted and set ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION
2026-06-18 13:30:09 +02:00
Jonathan Wakely 0356be0f6f Convert example/hashed.cpp to UTF-8 (#98)
This makes the file slightly larger, but that seems preferable because
almost all other Boost source files are encoded as UTF-8 these days.
2026-06-18 09:31:35 +02:00
joaquintides 1f61ddc1ec avoided bogus unitialized warnings in GCC 16.1, plus additional warning silencing (#97)
* added gcc-15, gcc-16
* explicitly constructed bfm_header everywhere
* reverted, silenced uninitialized warning
* moved silencing pragma inside header body
* made silencing pragma enclose entire multi_index_container definition
* abandoned pragma, deinlined header()
* tried an even more convoluted workaround
* type-erased member in header_holder
* s/static_cast/reinterpret_cast
* reverted, passed allocator and header explicitly in construction
* used passed header in construction rather than header()
* investigated if hit by https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119321
* documented GCC 16.1 flag
* avoided VS warning
2026-06-01 19:15:24 +02:00
joaquintides 0d48b7d14b documented #94 2026-04-24 11:45:18 +02:00
kraldan ac4971abc2 [bug] Fix severe performance bug caused by usage of float (#94)
* Replace `float` with `double` in hashed_index.hpp

* Fix formatting indents

* Reset changes

* Add fix from PR comment

comment: https://github.com/boostorg/multi_index/pull/94#issuecomment-4283474290

* forced both args of std::max to the same type

---------

Co-authored-by: Daniel Kral <daniel.kral@recombee.com>
Co-authored-by: joaquintides <joaquin.lopezmunoz@gmail.com>
2026-04-24 10:35:24 +02:00
joaquintides a47c9f57b4 updated macos and clang/ubuntu jobs (#92)
* updated macos and clang/ubuntu jobs

* added missing install
2026-01-23 22:08:06 +01:00
Andrey Semashev d260b4e524 Remove dependencies on Boost.StaticAssert. (#91)
Boost.StaticAssert has been merged into Boost.Config, so remove
the dependency.
2026-01-23 09:43:49 +01:00
joaquintides 179b5def1e removed C++03 polyfills (#90)
* removed simulated variadic function args

* removed detail/allocator_traits.hpp in favor of Boost.Core functionality

* removed usage of Boost.Move

* avoided pessimizing-move warnings

* removed usage of BOOST_DEDUCED_TYPENAME

* removed usage of BOOST_NO_CXX11_HDR_INITIALIZER_LIST

* removed usage of BOOST_NO_MEMBER_TEMPLATES

* removed usage of BOOST_NO_SFINAE

* removed leftover pp line

* removed usage of BOOST_NO_MEMBER_TEMPLATE_FRIENDS

* removed usage of BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP

* removed usage of BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL

* removed usage of BOOST_NO_CXX11_HDR_TYPE_TRAITS

* removed usage of BOOST_NO_CXX11_HDR_RANDOM

* removed usage of BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS

* removed usage of BOOST_NO_CXX11_DECLTYPE

* removed workarounds for pre-C++11 compilers

* updated dependencies

* removed usage of BOOST_MULTI_INDEX_MEMBER and similar in examples

* updated docs

* added C++11 badge

* updated as per  Alexander Grund's review

* editorial

* removed unneeded #includes
2025-11-07 18:37:41 +01:00
joaquintides eb993b1e23 made composite_key and associated class templates variadic (#88)
* made composite_key and associated types truly variadic

* added redundant ctor seemingly needed by MSVC 14.0

* moved redundant default ctor one derived class down

* temporarily disabled SFINAE for augmented_stdtuple(const boost_tuple_arg&)

* made previous permanent (more informative API)

* stylistic

* addes tests for std::tuple construction

* tested composite_key with long tuples

* stylistic

* tested composite_key assignability

* updated docs

* modernized test_composite_key
2025-11-05 20:16:25 +01:00
joaquintides 890f032939 removed Boost.MPL usage in favor of Boost.Mp11 (#87)
* omitted test_mpl_ops for now

* made IndexSpecifierList a Mp11 sequence

* made nested *_type_list's and tag Mp11 sequences

* leftover MPL->Mp11 change

* removed Clang 5.0 -std=c++1z as not supported by Mp11

* replaced boost::mpl::na with void as default index specifier arg

* removed Clang 5.0 -std=c++1z as not supported by Mp11 (Drone)

* replaced elementary MPL TMP with Mp11/std

* replaced elementary MPL TMP with Mp11/std (tests)

* leftover MPL #include

* suppressed potential narrowing conversion warnings

* enabled macro to support old interface, plus restored and augmented test_mpl_ops

* removed secondary dependency to MPL thru Iterator

* optimized Jamfile.v2

* added conditional support for old definition of tag

* updated MPL support macro in tests

* updated docs

* stylistic

* updated "cxxstd" in libraries.json

* disabled test_serialization for Clang 3.5-3.6 due to lack of support from Boost.SmartPtr

* fixed previous

* removed no longer necessary workaround

* removed redundant dependencies

* updated test description
2025-10-27 09:17:48 +01:00
Alexander Grund e2b50ef729 Update Link to regression test matrix in README (#83)
* Update Link to regression test matrix in README

* Use boost.org instead of boost.io
2025-09-19 09:06:49 +02:00
ivanpanch c2aca0975e Fix mistakes (#84)
* Update index.html

* Update basics.html

* Update indices.html

* Update debug.html

* Update techniques.html

* Update multi_index_container.html

* Update indices.html

* Update ord_indices.html

* Update hash_indices.html

* Update seq_indices.html

* Update rnd_indices.html

* Update key_extraction.html

* Update compiler_specifics.html

* Update performance.html

* Update examples.html

* Update tests.html

* Update indices.html

* Update key_extraction.html

* Update key_extraction.html

* Update multi_index_container.html

* Update rnd_indices.html
2025-09-08 10:18:24 +02:00
joaquintides 280d659bd9 dropped pre-C++11 msvc-9.0, msvc-10.0, msvc-11.0, msvc-12.0 2025-06-22 13:08:03 +02:00
joaquintides f4045037fa upgraded CI (#82) 2025-06-22 12:37:53 +02:00
joaquintides 07eb41065d updated cppalliance/droneubuntu23xx to 2404 (#78) 2024-12-09 11:00:54 +01:00
Alexander Grund 1da523aaf8 Fix node 20 issue on GHA CI (#77)
* Fix node 20 issue on GHA CI

* Use hosted node

* Remove macos-12

* Install xz
2024-12-09 09:06:41 +01:00
René Ferdinand Rivera Morell 60ff77c181 Add support for modular build structure. (#73)
* Make the library modular usable.

* Put back removing qualified boostcpp tag. As we need it until the Jamroot removes the qualified tag.

* Switch to library requirements instead of source. As source puts extra source in install targets.

* Remove uses of BOOST_ROOT in Jamfiles.

* Add requires-b2 check to top-level build file.

* Bump B2 require to 5.2

* Update copyright dates.

* Move inter-lib dependencies to a project variable and into the build targets.

* Update build deps.
2024-10-12 09:18:24 +02:00
Peter Dimov 47d36ce8e2 Avoid inclusion of deprecated header (#74) 2024-09-30 18:39:47 +02:00
joaquintides 162318b931 udpated CI 2024-09-30 18:38:11 +02:00
joaquintides e27a02aa81 [skip ci] updated README.md 2024-09-30 12:33:58 +02:00
joaquintides 5c17744f34 fixed documentation error 2024-03-15 09:49:30 +01:00
joaquintides 2b2c52a27f fixed #70 2023-09-09 17:06:06 +02:00
joaquintides 343cb4c6f3 fixed container size serialization in LLP64 2023-05-22 13:26:17 +02:00
joaquintides 3ad3171006 removed unneeded typename 2023-05-21 11:58:47 +02:00
joaquintides f8143b9ff9 fixed #68 2023-05-21 11:39:44 +02:00
joaquintides 0e55b48789 removed dependency from serialization 2023-03-27 18:34:49 +02:00
joaquintides b6d5c88629 Merge pull request #67 from Lastique/feature/remove_foreach_dep
Remove dependency on Boost.ForEach from CMakeLists.txt.
2023-03-27 18:31:45 +02:00
Andrey Semashev 7d8e20a59b Remove dependency on Boost.ForEach from CMakeLists.txt.
No public headers depend on Boost.ForEach headers, so the dependency
in CMakeLists.txt is not needed.

This dependency causes problems in downstream CI runs because boostdep
does not find the dependency on Boost.ForEach from public headers and
does not checkout Boost.ForEach git repo. This causes CMake errors
because it cannot resolve the Boost::foreach target.
2023-03-27 16:25:13 +03:00
joaquintides 6163f59747 editorial, extended test_iterators 2023-03-01 09:52:07 +01:00
joaquintides 4259987765 Merge pull request #66 from cmazakas/foreach_removal
Removal of dependency from Boost.Foreach
2023-03-01 09:39:15 +01:00
Christian Mazakas 28e00a0ea6 Add small test proving Boost.Foreach compatibility 2023-02-28 08:20:18 -08:00
Christian Mazakas 92de0326b5 Remove usage of boost/foreach_fwd.hpp in lieu of manual forward declaration + specialization 2023-02-28 08:20:18 -08:00
joaquintides 00abbbdb27 fixed header guard name 2023-02-27 09:56:45 +01:00
joaquintides c42c2509bc removed header-level dependency from Boost.Serialization 2023-02-26 19:16:45 +01:00
joaquintides eeac86a37e updated release notes 2022-12-28 12:44:10 +01:00
joaquintides 40bead0430 updated (C) 2022-12-28 12:43:35 +01:00
Michael Ford 4312c88ead Minor include refactors (#65)
* refactor: use type_traits/declval over utility/declval

The later is just an include for the former.

* refactor: use container_hash/hash* over functional/hash*

The later just include the former.
2022-12-28 12:34:58 +01:00
joaquintides a7716c7f16 updated copyright dates 2022-08-23 19:12:10 +02:00
Michael Ford ae95816ae8 refactor: use core/enable_if over utility/enable_if (#64)
The later is deprecated:
```cpp
// The header file at this path is deprecated;
// use boost/core/enable_if.hpp instead.

include <boost/core/enable_if.hpp>
```
2022-08-23 19:04:48 +02:00
joaquintides 2404754d42 fixed explanatory code as prompted by discussion in #63 2022-08-15 16:31:01 +02:00
Baoshuo Ren 45bb3c8b70 chore: bump macos runner version (#62)
GitHub Action is sunsetting the macOS 10.15 Actions runner. It will stop working intermittently until being completely removed by 2022-8-30: https://github.blog/changelog/2022-07-20-github-actions-the-macos-10-15-actions-runner-image-is-being-deprecated-and-will-be-removed-by-8-30-22
2022-08-01 10:13:07 +02:00
joaquintides 99f33def00 fixed #61 2022-07-01 09:59:56 +02:00
joaquintides ed8d49dc59 updated (C) year 2022-06-29 09:41:53 +02:00
theidexisted 6b2be7c601 Fix typo in doc (#60) 2022-06-29 09:39:46 +02:00
joaquintides fba66b0538 updated dates and release notes 2022-04-08 17:13:04 +02:00
Michael Ford a7e5cf843a refactor use core/ref.hpp over ref.hpp (#58)
The later has been deprecated:
```cpp

// The header file at this path is deprecated;
// use boost/core/ref.hpp instead.

```
2022-04-08 17:05:47 +02:00
joaquintides 647a60da24 updated revision dates 2022-04-03 16:29:38 +02:00
Michael Ford 2b78a77d6b refactor: use boost/core/noncopyable.hpp over boost/noncopyable.hpp (#57)
boost/noncopyable.hpp is deprecated
2022-04-03 15:27:18 +02:00
Jonathan Wakely 9847e2daf8 Change encoding to UTF-8 for doc/style.css (#55) 2022-02-05 13:03:19 +01:00
joaquintides 7c591a13aa improved performance of count in ranked indices (#56)
* count for ranked_index uses rank

Normally, count is calculated as the distance between iterators,
which takes linear time when count(x,comp) is comparable with n,
but for ranked indices we can subtract the values or rank,
reducing the complexity from log(n)+count(x,comp) to log(n).

* Added test for new count(x) and count(x,comp) in ranked_index

Both, the existing implementation of count from ordered_index and
the new implementation for ranked_index are compared with the
common sense. Positive results of this test show in particular that
the numbers produced by the new implementation are consistent with
those from the existing implementation and hence correct.

* Benchmark of count(): ordered_index vs ranked_index

A benchmark is added as count_benchmark.cpp in the 'example'
directory.

When the values of an index are unique, both implementations are
comparable (ranked_index is 10-15% faster).

However, for highly non-unique indices (like the age of people),
the new implementation in ranked_index outperforms ordered_index.
For 1 000 people of age in 0..99 ranked_index is ~2x faster,
for 10 000 people it is 12-13x faster, and
for 100 000 people it is 95-100x times faster.

For even more non-unique indices (like sex or the age of pupils)
or coarse comparison predicates (grouping people in age groups
like 0..9, 10..19 etc.) the gap in performance grows further.
For a comparison predicate comparing 'age/10' for age in 0..99,
similar gaps in performance occur already for 10x smaller
containers:
for 100 people count in ranked_index is 2x faster,
for 1 000 people it is ~9x faster,
for 10 000 people it is 95-100x faster,
for 100 000 people it is almost 1000x faster.

* Documentation updated with new complexity of count in ranked_index

* simplified Damian's contribution

* reorganized code

* covered ranked_index::count

* updated docs

Co-authored-by: DamianSawicki <86234282+DamianSawicki@users.noreply.github.com>
2022-02-05 12:59:43 +01:00
joaquintides 7c3cb66008 corrected statements on SCARYness 2021-08-30 20:55:10 +02:00
joaquintides 2026b94c12 fixed 1b38fdcc77 2021-08-30 09:20:29 +02:00
joaquintides 0179c2c041 suppressed spurious GCC type-limits warnings 2021-08-28 10:52:28 +02:00
joaquintides d86df5a52f kept max line length below 80 chars 2021-08-26 19:05:16 +02:00
joaquintides 5c8b26cd9b added missing #include's 2021-08-26 18:53:41 +02:00
joaquintides 1b38fdcc77 suppressed VS warnings 2021-08-26 18:41:45 +02:00
joaquintides a52810fc3d implemented merge operations (#49)
* initial draft

* modified appveyor.yml for this branch

* dropped BOOST_RV_REF
as it doesn't handle lvalue refs

* befriended index_base from all indices
so as to be grant access to final_extract_for_merge_ from an external container

* added rvalue ref merge
(test expected to fail in C++03)

* added explicit boost::move on rvalue ref
for the benefit of C++03 compilers

* fixed previous workaround

* refactored merge algorithm into multi_index_container

* added hashed_index::merge

* reimplemented sequenced_index::splice(position,x)

* added missing this->'s

* refactored SFINAEing code

* made sequenced_index::splice(position,x) exception robust

* reimplemented random_access_index::splice(position,x)

* micro-optimized legacy code in random_access_index::splice(position,x)

* added missing #include

* reimplemented sequenced_index::splice(position,x,i)

* reimplemented random_access_index::splice(position,x,i)

* reimplemented sequenced_index::splice(position,x,first,last)

* reimplemented random_access_index::splice(position,x,first,last)

* re-engineered sequenced_index::splice(position,x,i)
so that it works when source and destination belong to the same container

* stylistic

* re-engineered random_access_index::splice(position,x,i)
so that it works when source and destination belong to the same container

* re-engineered sequenced_index::splice(position,x,first,last)
so that it works when source and destination belong to the same container

* stylistic

* fixed bug in rvalue ref overload of sequenced_index::splice(position,x,first,last)

* fixed internal sequenced_index::splice(position,x,first,last) across different indices

* re-engineered random_access_index::splice(position,x,first,last)
the same way as done with sequenced_index

* replaced multi_index_container::merge_ with transfer_range_
so as to refactor some code in non-key-based indices

* fixed safe mode check for different-type containers

* hardened merge/splice tests

* s/BOOST_RV_REF/BOOST_FWD_REF

* called the right merge_different overload

* fixed problem with Boost.Move C++03 perfect fwd emulation

* updated (C) year

* allowed intra-container full splice

* required position==end() in intra-container full splice

* made pointwise splice return a pair<iterator,bool>

* added partial merge functionality to key-based indices
plus fixed a compile-time error with legacy splice code when applied to different-type indices

* suppressed unused variable

* fixed wrong signature in splice memfun

* made safe-mode iterators SCARY

* refactored any_container_view

* implemented safe iterator transfer in merge/splice

* reorganized internal deps

* stylistic

* automatically checked iterator invalidation upon merge/splice

* removed commented-out code

* checked allocator equality

* reimplemented random_access_index internal, cross-index splice in linear time

* updated docs

* reverted appveyor.yml
2021-08-19 10:41:03 +02:00
joaquintides 2a2282b270 Merge pull request #46 from sdarwin/feature/gha_fix_1
Update GitHub Actions CI file
2021-08-03 09:06:07 +02:00
sdarwin 1ab207ccc7 Update GitHub Actions CI file 2021-07-30 21:12:43 +00:00
joaquintides 647af59bdd installed pip with bootstrap script
as per https://github.com/boostorg/json/commit/8c7696ddb6431b51e96983597a25170a06a66da8
2021-07-29 13:09:14 +02:00
joaquintides 5623d2b9e2 added contains (#35) 2021-07-29 12:04:15 +02:00
joaquintides 3dad7f38a4 fixed #45 2021-07-08 19:41:40 +02:00
Peter Dimov 436c60cd09 Add CMakeLists.txt 2021-03-18 17:27:16 +02:00
joaquintides 23779b1577 Update README.md
fixed links to GitHub Actions CI results
2021-03-02 18:24:30 +01:00
joaquintides b3815602b2 Update README.md
added GitHub Actions CI badges
2021-03-02 18:12:51 +01:00
joaquintides 2f5c1b5fb5 Merge pull request #43 from sdarwin/githubactions
GitHub Actions config
2021-03-02 18:03:52 +01:00
sdarwin fa84d6f1ae Add GitHub Actions config [ci skip] 2021-03-02 15:02:46 +00:00
joaquintides 028d097cd9 Merge pull request #42 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-01-21 09:15:23 +01:00
Edward Diener 060c2951aa [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-20 15:34:48 -05:00
joaquintides d410fd952a Merge pull request #40 from sdarwin/droneupdate
remove TRAVIS_OS_NAME from drone script [ci skip]
2021-01-08 09:49:50 +01:00
sdarwin bd2f183055 remove TRAVIS_OS_NAME from drone script [ci skip] 2021-01-07 19:14:31 +00:00
joaquintides 2eb53f67e2 as per https://lists.boost.org/Archives/boost/2021/01/250603.php 2021-01-05 14:02:52 +01:00
joaquintides 32dfab2f9c added Drone badges 2021-01-05 13:08:19 +01:00
joaquintides 2546cb99bc reversed previous trivial change 2021-01-05 10:51:10 +01:00
joaquintides bd1cb7d171 trivial change to trigger Drone CI 2021-01-05 10:50:32 +01:00
joaquintides 59a4416a6e Merge pull request #39 from sdarwin/drone
Drone config
2021-01-05 10:49:51 +01:00
sdarwin 4795ae9d89 drone 2020-12-30 14:06:17 +00:00
joaquintides b685e11dfc stopped relying on stdlib function objects' ::result_type 2020-06-29 11:51:24 +02:00
joaquintides 9d1813aaad typo 2020-06-06 10:32:24 +02:00
joaquintides ece90a6eb4 un-named unused parameter 2020-05-11 15:37:17 +02:00
joaquintides 1b1e29d6e3 added workaround for https://github.com/boostorg/config/issues/336 2020-05-10 15:27:11 +02:00
joaquintides 53c11e1ea7 added missing #include 2020-05-10 13:58:16 +02:00
joaquintides e3fec3af57 fixed allocator_is_always_equal usage 2020-05-10 13:47:09 +02:00
joaquintides ed5a975059 provided pre-C++17 allocator_traits::is_always_equal 2020-05-10 13:33:36 +02:00
joaquintides 2271c1b9c6 added missing typename keyword 2020-05-10 12:26:17 +02:00
joaquintides 4a109e99e5 avoided deprecated #includes, fixed Boost.Move headers 2020-05-10 12:17:55 +02:00
joaquintides f8945d113e fixed interaction of C++03 boost::move with non-refd template params 2020-05-10 11:50:06 +02:00
joaquintides 85b6cdba91 SFINAEd test overload set 2020-05-10 11:01:50 +02:00
joaquintides 98091f99e6 added missing typename keyword 2020-05-10 10:12:17 +02:00
joaquintides ff3f612abb added missing template keywords 2020-05-10 10:11:51 +02:00
joaquintides 99430f9edd avoided deprecated #includes 2020-05-09 22:01:20 +02:00
joaquintides e69466039d implemented node extraction/insertion (#27) 2020-05-09 20:25:41 +02:00
joaquintides a766a08573 replaced erase_ backbone function with extract:_ 2020-05-01 20:36:38 +02:00
joaquintides 3a47a82947 simplified delete_node_ 2020-05-01 13:22:03 +02:00
joaquintides a34c774a05 made node structure independent of unique/non_unique flavor 2020-05-01 12:29:03 +02:00
joaquintides 382e41fa99 renamed internal typedefs to make room for public node_type 2020-05-01 11:46:51 +02:00
joaquintides 2374136ea8 clarified documentation on read/write key extractors (#32) 2020-04-19 21:10:57 +02:00
joaquintides ffbdc49bf2 typos (#32) 2020-04-18 11:59:45 +02:00
joaquintides 1c3ef66798 stopped #including deprecated <boost/bind.hpp> 2020-02-17 09:39:08 +01:00
joaquintides 61c732118e refactored rooted_allocator 2020-01-27 12:33:02 +01:00
joaquintides d7ad9185e8 spared one equal allocator swap 2020-01-27 12:14:03 +01:00
joaquintides 81dbe86f25 suppressed VS warnings 2020-01-26 13:24:55 +01:00
joaquintides 3e8928834c fixed allocator awareness test for move assignment 2020-01-26 12:59:37 +01:00
joaquintides adbb136e43 completed Boost.Move support for move_tracker 2020-01-26 12:40:35 +01:00
joaquintides ff46d35312 enabled Boost.Move support for move_tracker 2020-01-26 12:16:54 +01:00
joaquintides a8d34a56f7 made multi_index_container AllocatorAware (#30) 2020-01-26 11:52:23 +01:00
joaquintides 89b4ff7bbf abode by [depr.impldec] 2020-01-21 15:04:21 +01:00
joaquintides c9a21d79d6 used proper HTLM entities (#31) 2020-01-09 14:56:30 +01:00
joaquintides d4e81bbe7e fixed doc snippets (https://stackoverflow.com/a/58921647/213114) 2019-11-18 20:47:16 +01:00
joaquintides 264c062bf4 reverted Travis to Trusty (current default is Xenial) 2019-11-12 17:50:37 +01:00
joaquintides 3caea31bfc enabled ADL for internal swapping of user-provided objects (#29) 2019-11-09 12:59:55 +01:00
joaquintides a7ef250b9f avoided VS's spurious preprocessor warning 2019-06-11 17:10:01 +02:00
joaquintides 7508edc5c2 typo 2019-06-11 09:12:42 +02:00
joaquintides c24b639df1 refined previous workaround 2019-06-10 12:17:49 +02:00
joaquintides de709d6048 refactored previous workaround 2019-06-10 09:47:51 +02:00
joaquintides 68d3e4b5b2 tried workaround for buggy std::is_function in old version of libc++ 2019-06-09 21:38:42 +02:00
joaquintides c98519ca41 moved all AppVeyor work from VS2013 image to VS2015 image 2019-06-09 17:56:06 +02:00
joaquintides e49ae2b4c2 handled volatile/ref-qualified/noexcept memfun key extraction (#24) 2019-06-09 17:32:46 +02:00
joaquintides 32b7f257c2 reformatted 54302463e5 2019-02-28 18:35:42 +01:00
joaquintides 54302463e5 Merge pull request #22 from stac47/fix_multi_index_deprecated_copy
fixed GCC -Wdeprecated-copy
2019-02-28 18:25:20 +01:00
Laurent Stacul 55fb849c2c Fix gcc -Wdeprecated-copy 2019-02-28 16:02:41 +00:00
joaquintides bbb915bd34 updated (c) year 2019-02-25 17:18:27 +01:00
joaquintides 8ef40b12df Merge pull request #21 from MarcelRaad/extra-semi
fixed -Wextra-semi clang warnings
2019-02-25 17:15:26 +01:00
Marcel Raad 1933ca91b7 Fix -Wextra-semi clang warnings
Remove superfluous semicola after function bodies.
2019-02-25 13:40:22 +01:00
joaquintides 09ea3b91be fixed revised date 2019-02-20 11:21:53 +01:00
joaquintides 9504362e08 updated mentions to unordered associative containers (heads-up from #20) 2019-02-20 11:19:09 +01:00
joaquintides 5ecffb12b6 flattened out nested SVG 2019-01-03 09:32:29 +01:00
joaquintides 8dbab1978c made just another attempt at fixing SVG 2019-01-02 19:18:43 +01:00
joaquintides a611e3c504 made another attempt at CSP-clearing SVG file 2019-01-02 18:32:39 +01:00
joaquintides abf7c456e1 updated embedded SVG to comply with FF CSP 2019-01-02 13:32:14 +01:00
joaquintides 58f39df261 Update README.md 2019-01-02 10:58:02 +01:00
joaquintides cd8124a9d6 Update README.md 2019-01-02 10:57:12 +01:00
joaquintides f2922dd541 Update README.md 2019-01-02 10:56:56 +01:00
joaquintides 6de959eb78 added links to regression tests 2019-01-02 10:47:50 +01:00
joaquintides 454266c22c relinked badges to travis-ci.com 2019-01-02 09:33:44 +01:00
joaquintides 6698843328 avoided self-assign-overloaded Clang warnings 2018-12-31 12:54:27 +01:00
joaquintides dc1ac9d879 added/trimmed #include's 2018-12-31 10:59:06 +01:00
joaquintides adbd496248 stylistic 2018-12-31 10:13:37 +01:00
joaquintides 008b1a5ed6 completed previous fix 2018-12-31 10:06:27 +01:00
joaquintides ac377a6e7d fixed wrong copy construction as emplacement construction 2018-12-31 09:48:09 +01:00
joaquintides 131e3427ae farewelled boost/detail/allocator_utilities.hpp 2018-12-31 01:50:12 +01:00
joaquintides e45fdaa2ca added missing #include (for stylistic reasons) 2018-12-30 17:57:36 +01:00
joaquintides 1af32b3ad0 s/./, 2018-12-30 16:54:02 +01:00
joaquintides e38e118acf deleted duplicate definition 2018-12-30 16:46:33 +01:00
joaquintides 255a53240d silenced MSVC patronizing warnings 2018-12-30 16:35:05 +01:00
joaquintides a199da8fb0 reverted ec129437dc as useless 2018-12-30 16:32:35 +01:00
joaquintides 521b3bee9e expanded Travis toolsets (from smart_ptr's .travis.yml) 2018-12-30 16:14:16 +01:00
joaquintides c57a6771fd refactored 91f2116711 2018-12-30 14:59:14 +01:00
joaquintides 9acee043bc disabled MSVC 14.0 warning 2018-12-30 12:13:32 +01:00
joaquintides ec129437dc bypassed MSVC 12.0 bogus errors 2018-12-29 22:42:51 +01:00
joaquintides 8136196a4d expanded AppVeyor toolsets 2018-12-29 22:41:57 +01:00
joaquintides d9c62ea8ed shut down "unsigned>=0"-type tautological-compare Clang warnings 2018-12-29 21:33:28 +01:00
joaquintides edf9492ee1 fixed naming bug 2018-12-29 18:23:16 +01:00
joaquintides 26aa66b779 fixed naming bugs 2018-12-29 17:50:31 +01:00
joaquintides ecad16693f fixed name shadowing bug 2018-12-29 17:50:04 +01:00
joaquintides f11bacdbbc added Travis and AppVeyor support 2018-12-29 17:33:46 +01:00
joaquintides 18cea285e2 inherited size_type and difference_type from the allocator 2018-12-29 13:06:57 +01:00
joaquintides d6cd661119 renamed file 2018-09-03 09:25:51 +02:00
joaquintides c1889e33dc re-made test_key pass when !defined(BOOST_MULTI_INDEX_KEY_SUPPORTED) for the sake of test_all_main.cpp 2018-09-02 12:20:36 +02:00
joaquintides cfbf3f6fdc made test_key build conditional 2018-09-02 12:08:38 +02:00
joaquintides e86162cff8 made warn instead of fail when key is not supported 2018-08-30 11:27:53 +02:00
joaquintides 4f06b28a77 added one more fix to help MSVC 14.1 with template specialization partial ordering 2018-08-29 19:02:47 +02:00
joaquintides a3bf0de25b specialized on a non-auto-param'd class template to help MSVC 14.1 2018-08-26 12:53:43 +02:00
joaquintides 45266cd2a7 further tweaked key_impl to pursue MSVC 14.1 problem 2018-08-24 13:14:26 +02:00
joaquintides 26f85dfea8 made key_impl specialization partial order clearer to pin down problem with MSVC 14.1 2018-08-23 11:11:05 +02:00
joaquintides fe746a187c documented BOOST_MULTI_INDEX_KEY_SUPPORTED 2018-08-22 11:23:32 +02:00
joaquintides 35ba93a0eb avoided std::*[_t|_v] to extend compiler support 2018-08-20 10:08:41 +02:00
joaquintides 135b31fc3c fixed use of BOOST_MULTI_INDEX_KEY_SUPPORTED 2018-08-18 18:51:21 +02:00
joaquintides 504574a265 s/·/&middot; 2018-08-18 13:25:00 +02:00
joaquintides e8c1598e32 temporarily enabled test_key everywhere 2018-08-18 12:46:54 +02:00
joaquintides 72d4b74cfb attended expansion of key<> support to MSVC 2018-08-18 12:46:30 +02:00
joaquintides f31407d621 typo 2018-08-18 12:06:13 +02:00
joaquintides 0ac225601d detabbed 2018-08-17 13:16:39 +02:00
joaquintides 7cc508376c introduced C++17 terse key specification syntax 2018-08-17 13:07:53 +02:00
joaquintides 69488c737b editorial 2018-08-06 09:33:50 +02:00
joaquintides 7b77621323 avoided Boost.Move use for the sake of old GCC versions 2018-04-20 10:51:06 +02:00
joaquintides 9623bf0a7d addressed https://svn.boost.org/trac10/ticket/13518 2018-04-13 18:06:55 +02:00
joaquintides 4d21e89621 addressed https://svn.boost.org/trac10/ticket/13478 2018-03-13 22:05:01 +01:00
joaquintides 4753b325c5 reverted 350d337 and fixed void& issue 2018-01-08 10:52:21 +01:00
joaquintides 97e015d2e2 added missing #include 2018-01-03 21:41:55 +01:00
joaquintides 350d337348 avoided void& in non_std_allocator<void> 2018-01-03 21:34:46 +01:00
joaquintides 36b17f6de6 typo 2018-01-01 13:09:27 +01:00
joaquintides 2f21af1751 documented previous commit 2018-01-01 11:36:34 +01:00
joaquintides 91f2116711 Merge pull request #14 from DanielaE/fix/replace-deprecated-allocator-members
Most members of std::allocate are deprecated in C++17
2018-01-01 11:08:35 +01:00
Daniela Engert 58c42a46c1 Most members of std::allocate are deprecated in C++17
Replace them by their cousins from std::allocator_traits.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-12-31 14:39:35 +01:00
joaquintides 8a8dee1357 removed C++11 parlance 2017-11-25 22:05:44 +01:00
joaquintides 5c5b1e95d4 s/>>/> > 2017-11-24 16:47:50 +01:00
joaquintides 7eb3b609d8 stylistic 2017-11-24 16:45:48 +01:00
joaquintides 5744230acf protected against overloaded operator& 2017-11-23 23:26:53 +01:00
joaquintides 3613e2287b updated release notes 2017-09-21 11:12:26 +02:00
joaquintides 18d6e7525a Merge pull request #13 from ecatmur/develop
Avoid double promotion and unnecessary casts
2017-09-21 09:49:13 +02:00
Ed Catmur 7999b663aa Missed one 2017-09-19 18:15:31 +01:00
Ed Catmur cd2db772ea Fix double promotion and unnecessary casts
When performing max load factor calculations, cast operands to float (not double), perform operations in float, and don't cast result to float if it is already in float. Fixes warnings with -Wdouble-promotion and -Wuseless-cast.
2017-09-19 18:02:43 +01:00
joaquintides bc5a3bdb67 updated last revision date 2017-08-29 08:41:43 +02:00
joaquintides 07749abe6f Merge pull request #12 from kariya-mitsuru/fix-typo
Fix typo
2017-08-29 08:33:40 +02:00
Mitsuru Kariya 53607ec851 Fix typo 2017-08-29 10:03:15 +09:00
joaquintides b9a4467f34 addressed https://svn.boost.org/trac/boost/ticket/12542 2017-08-24 23:41:35 +02:00
joaquintides 43d835120e fixed links 2017-07-07 11:39:28 +02:00
joaquintides 3e1095d609 fixed [12955] 2017-04-10 12:36:25 +02:00
joaquintides df022fa659 shut down promotes_1st_arg/promotes_2nd_arg for MSVC 7.1 2017-01-08 13:24:13 +01:00
joaquintides 4a5c4fc1a1 removed dependency from BOOST_IS_CONVERTIBLE intrinsic 2016-12-14 11:27:41 +01:00
joaquintides b469742547 restricted previous fix to GCC >=4.6 as "#pragma GCC diagnostic push|pop" is only supported since that version 2016-03-11 09:45:24 +01:00
joaquintides 1f29a85e42 refactored previous commit 2016-03-10 10:33:29 +01:00
joaquintides a63646f567 suppressed strict aliasing warnings related to boost::aligned_storage 2016-03-09 23:56:07 +01:00
joaquintides e23ffaa1f3 changed email address 2016-01-19 08:26:40 +01:00
joaquintides c055516320 clarified permissible usage of modify functions as per https://svn.boost.org/trac/boost/ticket/11801 2015-11-26 20:29:19 +01:00
joaquintides 62dbfff9c8 typos 2015-11-24 08:47:51 +01:00
joaquintides 096741d58b updated (C) year as per previous commit 2015-11-24 08:36:32 +01:00
joaquintides 8a2703ff2b Merge pull request #9 from zerotypos-found/fix_typo
typos
2015-11-24 08:14:28 +01:00
zerotypos-found 1db23a5f1c Fix typo in comment and docs. 2015-11-24 12:08:02 +09:00
joaquintides 1f4d33012b suppressed trivial warnings 2015-11-10 08:16:50 +01:00
joaquintides 84e70f08f2 fixed MSVC 7.1 overload bug as described in http://lists.boost.org/Archives/boost/2015/10/226135.php 2015-10-19 09:42:19 +02:00
joaquintides acda0c8abd typo 2015-08-19 10:29:49 +02:00
joaquintides 10e6c0ef87 Revert "insisted on suppressing -Wstrict-aliasing warnings"
This reverts commit 64848d0397.
2015-07-28 08:25:04 +02:00
joaquintides 64848d0397 insisted on suppressing -Wstrict-aliasing warnings 2015-07-27 12:47:00 +02:00
joaquintides bbad86c193 fixed interoperability problem with Qt around foreach macro 2015-07-23 08:33:20 +02:00
joaquintides ee364b7150 fixed usage of wrong integral type 2015-06-14 19:31:18 +02:00
joaquintides b7e4086682 missing template parameter 2015-06-13 21:28:44 +02:00
joaquintides 14257ba9ce suppressed -Wstrict-aliasing warnings 2015-06-08 19:38:29 +02:00
joaquintides 14c16a3bae suppressed signed/unsigned comparison warning 2015-06-08 14:53:44 +02:00
joaquintides 09afa8aa99 suppressed narrowing conversion warning 2015-06-02 08:59:44 +02:00
joaquintides f4c9492a54 suppressed narrowing conversion warning 2015-06-02 08:43:29 +02:00
joaquintides 0181f7dd8e suppressed -Wunused-local-typedefs warnings 2015-06-02 08:21:48 +02:00
joaquintides 8ece62829b fixed grammar 2015-05-04 08:18:13 +02:00
joaquintides 4ee43076b8 fixed (7 year old!) null-dereferencing UB likely to pop up with non-raw allocator::pointer's 2015-04-26 19:53:15 +02:00
joaquintides a26d889584 fixed previous fix 2015-04-23 10:55:39 +02:00
joaquintides 3f8d49acea applied rewording of https://github.com/boostorg/multi_index/pull/6 2015-04-22 12:21:45 +02:00
joaquintides cff87caa7c document the fact that deletion in ranked indices is log(n) in contrast with ordered indices where it is constant 2015-04-21 23:08:02 +02:00
joaquintides 6b64f02cd3 fixed hopefully last couple of glitches 2015-04-21 21:11:41 +02:00
joaquintides c26c180916 more glitches fixed 2015-04-21 15:40:53 +02:00
joaquintides 23113b4dd6 fixed more glitches 2015-04-20 23:12:46 +02:00
joaquintides a4563aa66f toned message down 2015-04-20 20:59:03 +02:00
joaquintides b0068335bb fixed glitches in previous commit 2015-04-20 12:57:25 +02:00
joaquintides d0a7194db7 added ranked indices, plus some doc stylistic updates 2015-04-19 21:10:31 +02:00
joaquintides 07977932ea Sun C++ compiler (incorrectly?) complained about type of bucket_array_base<>::sizes being incomplete at the point of instantiation of bucket_array_base<>::size_index 2015-04-12 18:27:36 +02:00
joaquintides 7683cec919 implemented N4190 2015-03-25 20:44:06 +01:00
joaquintides 19505ffa5f fixed conversion warning 2015-02-23 12:36:29 +01:00
joaquintides ca05a953bd accompanied migration of gcd from Boost.Integer to Boost.Math 2015-01-15 08:25:56 +01:00
joaquintides c3cbe4df42 updated (C) year as per previous commit 2015-01-08 19:43:37 +01:00
joaquintides c5770230bf Merge pull request #4 from romanek-adam/warning_fix
Got rid of an unused typedef which caused a compiler warning
2015-01-08 19:25:02 +01:00
Adam Romanek 85625ecd5d Got rid of an unused typedef which caused a compiler warning 2015-01-08 15:31:55 +01:00
joaquintides c41fad927a defaulted is_transparent if BOOST_NO_SFINAE_EXPR 2014-11-18 22:43:54 +01:00
joaquintides 27eea86ff9 extended is_transparent_class to compilers without final support 2014-11-18 08:19:11 +01:00
joaquintides 9732279d77 typo 2014-11-12 13:19:49 +01:00
joaquintides f471d61d0b reworded statement in latest doc change 2014-11-11 23:03:00 +01:00
joaquintides e18ece1ec1 doc improvement as per http://lists.boost.org/Archives/boost/2014/11/217502.php 2014-11-11 21:24:11 +01:00
joaquintides d45c8e0991 covered convertible but non-copyable classes 2014-11-06 12:33:04 +01:00
joaquintides 08fe6a360a suppressed Coverity warnings 2014-11-05 08:37:58 +01:00
joaquintides 71fd63ce7a extended lookup efficiency improvement technique to (pointer to) function types 2014-11-02 19:02:34 +01:00
joaquintides 57ab570240 documented latest efficiency improvement 2014-11-02 16:07:53 +01:00
joaquintides 2170318c39 added missing _'s 2014-11-02 01:04:16 +01:00
joaquintides 6aae9471bb >> -> > > 2014-11-01 20:36:08 +01:00
joaquintides 79541fce51 improved lookup efficiency in the event of implicit conversion to key_type 2014-11-01 15:24:31 +01:00
joaquintides 87ff899ceb polished small test utility 2014-08-20 20:53:30 +02:00
joaquintides 6d6bb75504 added interoperability of std::tuples with composite keys 2014-08-20 11:19:40 +02:00
joaquintides 87cb3fe3ad Merge pull request #2 from danieljames/metadata
Create metadata file.
2014-08-18 16:40:17 +02:00
Daniel James 3547ed34b8 Add metadata file. 2014-08-18 15:07:51 +01:00
joaquintides c389bd462f std::initializer_list<T>::iterator --> const T* to cope with old versions of libstdc++ 2014-07-21 19:18:12 +02:00
joaquintides d0feaa8963 fixed broken link to BOOST_ASSERT docs 2014-07-16 14:14:47 +02:00
joaquintides f6ef739fc9 fixed https://svn.boost.org/trac/boost/ticket/9798 2014-03-25 07:53:03 +01:00
joaquintides a9c06ce5c1 avoided potential ADL kick-in 2014-03-17 14:45:27 +01:00
joaquintides 26d215e063 fixed https://svn.boost.org/trac/boost/ticket/9665 2014-02-13 20:06:34 +01:00
joaquintides 97187ae449 fixed https://svn.boost.org/trac/boost/ticket/9658 2014-02-12 08:26:13 +01:00
joaquintides 1f450f5322 fixed typo 2014-01-16 08:49:05 +01:00
joaquintides 67cb8a2f9b cat stepped on the keyboard 2014-01-11 23:08:59 +01:00
joaquintides a5d2e189ff hashed index large performance improvements 2014-01-09 03:41:26 +01:00
joaquintides 86d7b3ef6e copied content from develop after wrongly made merge 2013-12-25 12:36:32 +01:00
joaquintides 3239677c40 Merge branch 'develop' 2013-12-24 13:22:09 +01:00
joaquintides 802543fd94 created first merge point for Git 2013-12-24 13:11:55 +01:00
joaquintides fdd4934c23 added == and != operators to hashed indices 2013-12-04 00:22:06 +01:00
Joaquín M López Muñoz 041c9ec779 hashed index slight performance improvements
[SVN r86758]
2013-11-18 18:20:44 +00:00
Joaquín M López Muñoz 121977f5a4 (hopefully) fixed use of sizeof on an incomplete type
[SVN r86731]
2013-11-16 21:39:01 +00:00
Joaquín M López Muñoz 5b45403d9a cleaned -Wshadow warnings
[SVN r86730]
2013-11-16 21:23:34 +00:00
Joaquín M López Muñoz a37acffb89 typo
[SVN r86718]
2013-11-16 12:51:13 +00:00
Joaquín M López Muñoz 2e1ba3df49 hashed index performance improvements
[SVN r86717]
2013-11-16 12:49:13 +00:00
Michel Morin a01876551b Merge r86524 (Correct broken links to C++ standard papers); fixes #9212
[SVN r86673]
2013-11-13 03:22:55 +00:00
Joaquín M López Muñoz 41f29cd238 fixed in-header static var def problem
[SVN r86651]
2013-11-12 15:44:19 +00:00
Joaquín M López Muñoz d5db77efa5 accelerated hash->bucket mapping
[SVN r86597]
2013-11-09 12:02:36 +00:00
Michel Morin d338464a11 Correct broken links to C++ standard papers. Refs #9212.
[SVN r86524]
2013-10-30 12:51:24 +00:00
Joaquín M López Muñoz 7d04e36f00 documented a particular deviation of hashed indices from the standard
[SVN r86371]
2013-10-20 16:39:12 +00:00
Joaquín M López Muñoz 2cc3436492 hashed index performance improvement
[SVN r86370]
2013-10-20 16:19:16 +00:00
Joaquín M López Muñoz 2a822dd1d1 one trivial and one subtle (http://stackoverflow.com/a/12187709/213114) fix
[SVN r86281]
2013-10-13 09:14:57 +00:00
Joaquín M López Muñoz 3bff1885d1 removed support for compilers without template partial specialization
[SVN r86269]
2013-10-12 19:59:48 +00:00
Joaquín M López Muñoz 27923b8620 * Reformatted and completed legacy code removal patches from Stephen Kelly (note: this patch treads on changesets [86244] and [82545], will restore later)
* Changed hashed indices internal data structure
* Changed hashed index iterator serialization
* Added reserve to hashed indices
* noexcept specification
* Lazy node allocation in insertion
* Doc typos

[SVN r86264]
2013-10-12 15:30:35 +00:00
Stephen Kelly add77e70c3 Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
These evaded scripting.

[SVN r86249]
2013-10-11 23:22:36 +00:00
Stephen Kelly 38bb0ed41c Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#else...#endif blocks.

[SVN r86245]
2013-10-11 23:17:48 +00:00
Stephen Kelly f64736a9a6 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#endif conditions.

[SVN r86244]
2013-10-11 23:15:00 +00:00
Stephen Kelly b4733fb78a MultiIndex: Remove obsolete MSVC version checks.
[SVN r86101]
2013-10-01 08:41:26 +00:00
Stephen Kelly 86a69d7cd8 MultiIndex: Remove obsolete GCC version check.
[SVN r86100]
2013-10-01 08:41:13 +00:00
Stephen Kelly de188091f2 MultiIndex: Remove obsolete MSVC version checks.
[SVN r86022]
2013-09-30 00:17:47 +00:00
Stephen Kelly b036cfdb49 MultiIndex: Remove obsolete prevent_eti workaround.
It was previously provided for old MSVC.

[SVN r85954]
2013-09-26 13:04:38 +00:00
Stephen Kelly 9b580ad95a MultiIndex: Remove obsolete MSVC version checks.
[SVN r85953]
2013-09-26 13:04:04 +00:00
Stephen Kelly 8616eb47c1 Remove obsolete MSVC check from pragma guard
git grep -h -B1 "^#\s*pragma once" | grep -v pragma | sort | uniq

is now clean.

[SVN r85952]
2013-09-26 13:02:51 +00:00
Stephen Kelly fd153213ec Remove use of obsolete BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE macro.
[SVN r85897]
2013-09-25 10:29:59 +00:00
Stephen Kelly f5ae9390cf Remove use of obsolete BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE{,_SPEC} macro.
[SVN r85896]
2013-09-25 10:29:44 +00:00
Stephen Kelly d73379b055 Remove use of obsolete BOOST_EXPLICIT_TEMPLATE_NON_TYPE macro.
[SVN r85895]
2013-09-25 10:29:10 +00:00
Stephen Kelly 8dfd2f9e64 Remove use of obsolete BOOST_EXPLICIT_TEMPLATE_TYPE{,_SPEC} macros.
[SVN r85894]
2013-09-25 10:28:56 +00:00
Joaquín M López Muñoz 590e3d1511 merged [85497] from trunk
[SVN r85509]
2013-08-29 06:10:38 +00:00
Joaquín M López Muñoz c564f8f5dd suppressed preliminary solution to EWG issue 2193 due to problems described at http://cplusplus.github.io/LWG/lwg-active.html#2193
[SVN r85497]
2013-08-28 06:38:30 +00:00
Joaquín M López Muñoz 078944b1b5 merged [85175] from trunk
[SVN r85176]
2013-07-30 15:32:01 +00:00
Joaquín M López Muñoz 527f4a5061 fixed typo
[SVN r85175]
2013-07-30 15:27:00 +00:00
Joaquín M López Muñoz 0bc802ad7d merged [85001], [85004], [85005], [85016], [85017], [85018], [85022], [85028], [85099] and [85100] from trunk
[SVN r85146]
2013-07-24 07:52:40 +00:00
Joaquín M López Muñoz 83a3b450ae suppressed spurious warning
[SVN r85100]
2013-07-22 07:04:09 +00:00
Joaquín M López Muñoz 72410dc3c6 added missing #include
[SVN r85099]
2013-07-22 06:52:16 +00:00
Joaquín M López Muñoz ef90efe473 deleted duplicate bookmark
[SVN r85028]
2013-07-14 08:39:59 +00:00
Joaquín M López Muñoz 25f76950f4 added missing semicolon and kept maximum line width at 80
[SVN r85022]
2013-07-13 14:54:35 +00:00
Joaquín M López Muñoz 84c65c35cb fixed typos with initializer lists and redefined variables
[SVN r85018]
2013-07-12 18:21:50 +00:00
Joaquín M López Muñoz 209c1afd04 properly made employee Boost.Move-wise copyable and movable
[SVN r85017]
2013-07-12 18:19:20 +00:00
Joaquín M López Muñoz 2935086121 properly called move placement new
[SVN r85016]
2013-07-12 18:17:29 +00:00
Joaquín M López Muñoz fe328c2800 deleted leftover
[SVN r85005]
2013-07-12 08:33:26 +00:00
Joaquín M López Muñoz 3e92a5b2a8 fixed typos in usage of variadic templates
[SVN r85004]
2013-07-11 15:03:39 +00:00
Joaquín M López Muñoz 80a10c2d72 * multi_index_container is now efficiently movable.
* Initializer lists supported.
* Emplace functions provided.
* Non-copyable elements (such as std::unique_ptr<T>) supported. This includes insertion of a range [first,last) where the iterators point to a type that is convertible to that of the element: no copy construction happens in the process.
* Random access indices provide shrink_to_fit().
* The following classes are deprecated:
  - member_offset,
  - const_mem_fun_explicit,
  - mem_fun_explicit,
  - composite_key_result_equal_to,
  - composite_key_result_less,
  - composite_key_result_greater,
  - composite_key_result_hash.

[SVN r85001]
2013-07-10 21:54:06 +00:00
Joaquín M López Muñoz d2f0ef79a2 merged [83058] from trunk
[SVN r83078]
2013-02-22 06:51:48 +00:00
Joaquín M López Muñoz 0d4bf54658 fixed #8129
[SVN r83058]
2013-02-21 10:11:30 +00:00
Joaquín M López Muñoz 0f583940c9 merged [82897], [82970] and [82993] from trunk
[SVN r83003]
2013-02-19 14:49:33 +00:00
Joaquín M López Muñoz 9b0382bde3 strengthened unused var warning avoidance
[SVN r82993]
2013-02-19 07:11:07 +00:00
Joaquín M López Muñoz 76931bdbd3 stopped using Boost.Test in favor of <boost/detail/lightweight_test.hpp> framework
[SVN r82970]
2013-02-18 09:10:37 +00:00
Joaquín M López Muñoz 6452e4db53 fixed #8034
[SVN r82897]
2013-02-15 06:51:48 +00:00
Joaquín M López Muñoz b35a722129 merged [75643] from trunk
[SVN r75691]
2011-11-27 13:52:14 +00:00
Joaquín M López Muñoz 2ef40ef45a suppressed a potential narrow conversion warning described in ticket #3365
[SVN r75643]
2011-11-24 08:07:35 +00:00
Joaquín M López Muñoz 67f9c5b3ab merged [73498] from trunk
[SVN r73518]
2011-08-03 21:03:48 +00:00
Joaquín M López Muñoz 867a0fb9c9 fixed #5741
[SVN r73498]
2011-08-03 06:31:26 +00:00
Joaquín M López Muñoz 026fab85aa merged [71770] from trunk
[SVN r71810]
2011-05-08 11:38:13 +00:00
Joaquín M López Muñoz bac508586e fixed #5488
[SVN r71770]
2011-05-06 19:56:06 +00:00
Joaquín M López Muñoz 71fbbf1754 merged [71671] from trunk
[SVN r71768]
2011-05-06 19:47:26 +00:00
Joaquín M López Muñoz 84e34e45c3 merged [69540], [69632] and [69720] from trunk
[SVN r71767]
2011-05-06 19:38:25 +00:00
Joaquín M López Muñoz 1186efb3f0 fixed problem reported at http://lists.boost.org/boost-users/2011/05/68022.php
[SVN r71671]
2011-05-02 15:06:01 +00:00
Ralf W. Grosse-Kunstleve f0c0ae11a8 boost/multi_index/detail/scope_guard.hpp: fixing typo to restore g++ (and possibly other) builds
[SVN r69720]
2011-03-08 17:33:30 +00:00
Thorsten Jørgen Ottosen ebb7d18ce6 update with make_guard_if and varients
[SVN r69632]
2011-03-07 21:50:12 +00:00
Joaquín M López Muñoz 3e9d0232d2 closed #5260
[SVN r69540]
2011-03-04 08:06:42 +00:00
Steven Watanabe 55723474d2 Revert [67111] (addition of boost/detail/iomanip.hpp) and all the commits that depend on it. ([68137], [68140], [68141], [68154], and [68165]).
[SVN r68168]
2011-01-15 08:11:51 +00:00
Bryce Adelstein-Lelbach 1bf606a75d Replacing the use of <iomanip> with <boost/detail/iomanip.hpp> across Boost.
On Linux, GNU's libstdc++, which is the default stdlib for icc and clang,
cannot parse the <iomanip> header in version 4.5+ (which thankfully neither
compiler advises the use of yet), as it's original C++98-friendly
implementation has been replaced with a gnu++0x implementation.
<boost/detail/iomanip.hpp> is a portable implementation of <iomanip>, providing
boost::detail::setfill, boost::detail::setbase, boost::detail::setw,
boost::detail::setprecision, boost::detail::setiosflags and
boost::detail::resetiosflags. 



[SVN r68140]
2011-01-14 02:35:58 +00:00
Joaquín M López Muñoz 768432afcb merged [61482] from trunk
[SVN r64324]
2010-07-25 10:44:55 +00:00
Joaquín M López Muñoz 48eab15fc0 merged [64322] from trunk
[SVN r64323]
2010-07-25 10:19:38 +00:00
Joaquín M López Muñoz 7b1bcc810d completed fix in [64312] and [64317]
[SVN r64322]
2010-07-25 10:12:38 +00:00
Joaquín M López Muñoz 13842a23dc merged [64317] from trunk
[SVN r64318]
2010-07-24 19:36:50 +00:00
Joaquín M López Muñoz 78a83060f7 completed fix in [64312]
[SVN r64317]
2010-07-24 19:31:45 +00:00
Joaquín M López Muñoz e4771a0fae merged [64312] from trunk
[SVN r64313]
2010-07-24 09:20:29 +00:00
Joaquín M López Muñoz bf08ab429c synced with silent yet backwards-compatibility-breaking change of serialization::version<T>:value type from unsigned int to int in [62358]
[SVN r64312]
2010-07-24 09:17:01 +00:00
Joaquín M López Muñoz a739892808 fixed #4130
[SVN r61482]
2010-04-22 11:36:27 +00:00
Joaquín M López Muñoz eb1f2a98b7 merged [59582] from trunk
[SVN r59638]
2010-02-11 19:28:27 +00:00
Joaquín M López Muñoz 80517e00d7 eliminated dubious use of preprocessor
[SVN r59582]
2010-02-08 15:56:06 +00:00
Joaquín M López Muñoz 215d795984 merged [58485] and [59443] from trunk
[SVN r59525]
2010-02-06 14:38:28 +00:00
Joaquín M López Muñoz 4223235333 completed fix in [58485] with proper handling of value_type serialization class versioning
[SVN r59443]
2010-02-03 14:29:55 +00:00
Joaquín M López Muñoz efce67f27b reverted [58517]
[SVN r58847]
2010-01-09 18:17:59 +00:00
Joaquín M López Muñoz 5fd288b095 merged [58485] from trunk
[SVN r58517]
2009-12-23 18:01:35 +00:00
Joaquín M López Muñoz 9dfc424d7a handled serialization of non default constructible values
[SVN r58485]
2009-12-22 07:20:41 +00:00
Joaquín M López Muñoz 588e7657f3 merged [57541] and [58472] from trunk
[SVN r58473]
2009-12-21 10:23:36 +00:00
Joaquín M López Muñoz 270d048f12 fixed #3778
[SVN r58472]
2009-12-21 09:54:44 +00:00
Joaquín M López Muñoz 604128d17a suppressed MSVC /W4 C4512 warning
[SVN r57541]
2009-11-10 10:18:55 +00:00
Troy D. Straszheim 4c3b315b0b rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Troy D. Straszheim d2efd9d5ed rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Joaquín M López Muñoz b185884ffe merged [56829] from trunk
[SVN r56831]
2009-10-14 16:13:13 +00:00
Joaquín M López Muñoz 6b58056716 updated according to latest regression tests results
[SVN r56829]
2009-10-14 15:04:13 +00:00
Joaquín M López Muñoz f88fb07ae8 merged [56354] from trunk
[SVN r56385]
2009-09-26 12:54:43 +00:00
Joaquín M López Muñoz 7d1417fe8c fixed #3462
[SVN r56354]
2009-09-22 13:29:08 +00:00
Joaquín M López Muñoz 718559b87f merged [55994] and [55995] from trunk
[SVN r56111]
2009-09-08 20:20:35 +00:00
Joaquín M López Muñoz 12ba0771e8 documented [55994]
[SVN r55995]
2009-09-03 12:29:42 +00:00
Joaquín M López Muñoz fd2b4ede68 fixed #3365
[SVN r55994]
2009-09-03 12:11:59 +00:00
Troy D. Straszheim 5e50c69465 Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Troy D. Straszheim 180f64dc11 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Joaquín M López Muñoz ff51956131 merged [55055] and [55058] from trunk
[SVN r55081]
2009-07-22 15:16:28 +00:00
Joaquín M López Muñoz 86059ad43f updated according to latest regression tests results
[SVN r55058]
2009-07-21 11:41:18 +00:00
Joaquín M López Muñoz b14efa6fbf documented tag_list
[SVN r55055]
2009-07-21 09:59:35 +00:00
Joaquín M López Muñoz 3199ff1b44 merged up to [53676] from trunk
[SVN r53730]
2009-06-07 18:44:00 +00:00
Joaquín M López Muñoz 9c8c001d5d added workaround for IBM XL C/C++
[SVN r53676]
2009-06-06 10:46:10 +00:00
Joaquín M López Muñoz 06b509b35c provided erase() reentrancy even in invariant checking mode
[SVN r53633]
2009-06-04 13:05:10 +00:00
Joaquín M López Muñoz 45adb9c08a added qualifier to solve ambiguity with std::make_tuple
[SVN r53301]
2009-05-27 12:26:43 +00:00
Joaquín M López Muñoz 436ea292c6 handcrafted the element type of the bimap example for the same reasons as explained in [53273]
[SVN r53275]
2009-05-26 08:59:47 +00:00
Joaquín M López Muñoz a5210bff85 handcrafted pair_of_ints to guarantee that first and second belong to pair_of_ints proper and not to some implementation-specific base class, which happens with std::pair in MSVC 10 thus precluding the use of boost::multi_index::member as per 14.3.2/5 (no conversions applied to pointer to member functions template arguments).
[SVN r53273]
2009-05-26 06:34:33 +00:00
Joaquín M López Muñoz 1eebcfcf5f fixed #3076
[SVN r53246]
2009-05-25 12:20:07 +00:00
Joaquín M López Muñoz 6d2c3985f0 merged rev [52078] from trunk
[SVN r52101]
2009-04-01 08:45:12 +00:00
Joaquín M López Muñoz 8290474391 updated according to latest regression tests results
[SVN r52078]
2009-03-31 16:12:23 +00:00
Troy D. Straszheim d3e74bc941 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Joaquín M López Muñoz f5976c1695 merged rev. 50321 from trunk
[SVN r50328]
2008-12-19 19:11:40 +00:00
Joaquín M López Muñoz c80e451d22 updated according to latest regression tests results
[SVN r50321]
2008-12-19 07:53:46 +00:00
Joaquín M López Muñoz b61b58abfa merged up to rev. 49674 from trunk
[SVN r50300]
2008-12-16 21:00:30 +00:00
Joaquín M López Muñoz 90bc0b7662 suppressed MSVC warning in composite_key, deprecated nth_index_iterator and family, some stylistic changes in the tutorial.
[SVN r49674]
2008-11-10 14:49:57 +00:00
Michael A. Jackson 5d016b4003 Updating dependency information for modularized libraries.
[SVN r49628]
2008-11-07 17:05:27 +00:00
Michael A. Jackson 11f09a3558 Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
Michael A. Jackson 03ebcdd0f4 Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
Joaquín M López Muñoz d026f22be0 merged rev. 49142 from trunk
[SVN r49148]
2008-10-06 17:54:07 +00:00
Joaquín M López Muñoz 62911d5198 updated according to latest regression tests results
[SVN r49142]
2008-10-06 13:10:32 +00:00
Joaquín M López Muñoz 8c5ac57c6a merged rev. 48728 from trunk
[SVN r48774]
2008-09-14 16:36:06 +00:00
Joaquín M López Muñoz 05e70771fd fixed #2313
[SVN r48728]
2008-09-11 07:13:11 +00:00
Joaquín M López Muñoz df5eb5b646 merged rev. 48444 from trunk
[SVN r48513]
2008-09-01 15:27:55 +00:00
Joaquín M López Muñoz 6b5f74732b fixed #2257
[SVN r48444]
2008-08-29 12:36:56 +00:00
Joaquín M López Muñoz c2d5785ae8 merged rev. 47225 from trunk
[SVN r47234]
2008-07-08 16:38:25 +00:00
Joaquín M López Muñoz a404be8a6b stylistic change as per Boris Gubenko's advice
[SVN r47225]
2008-07-08 15:08:11 +00:00
Joaquín M López Muñoz ebf92487ae merged rev. 47071 from trunk
[SVN r47076]
2008-07-04 15:08:59 +00:00
Joaquín M López Muñoz 47b98dd304 updated according to latest regression tests results
[SVN r47071]
2008-07-04 08:02:32 +00:00
Joaquín M López Muñoz bd8ea1bc86 merged up to rev. 47041 from trunk
[SVN r47045]
2008-07-03 16:51:53 +00:00
Joaquín M López Muñoz d881480b52 updated according to latest regression tests results
[SVN r47041]
2008-07-03 14:40:14 +00:00
Joaquín M López Muñoz 15accb2836 Boost 1.36 version of Boost.MultiIndex
passim: supressed non-ASCII chars in C++ code
bidir_node_iterator.hpp: deleted unused template parameter
bucket_array.hpp: avoided allocator<void> instantiations
hash_index_iterator.hpp: avoided allocator<void> instantiations
hash_index_node.hpp: avoided allocator<void> instantiations, renamed var
ord_index_node.hpp: avoided allocator<void> instantiations
rnd_index_loader.hpp: avoided allocator<void> instantiations
rnd_index_node.hpp: avoided allocator<void> instantiations
rnd_index_ptr_array.hpp: avoided allocator<void> instantiations
rnd_node_iterator.hpp: deleted unused template parameter
seq_index_node.hpp: avoided allocator<void> instantiations
hashed_index.hpp: rewritten modify_ so that elements with unmodified key do not change position
multi_index_container.hpp: added allocator ctor
acknowledgements.html: added acknowledgements for Boost 1.36
compiler_specifics.html: typo
hash_indices.html: documented updating functions behavior wrt unmodified keys, formatting typos
key_extraction.html: formatting typos
multi_index_container.html: added allocator ctor, formatting typos
ord_indices.html: documented updating functions behavior wrt unmodified keys, formatting typos
rnd_indices.html: formatting typos
seq_indices.html: formatting typos
release_notes.html: added release notes for Boost 1.36
hashed.cpp: blocked Boost inspect tool check for ASCII only chars
non_std_allocator.hpp: removed void specialization to verify that no allocator<void> instantiations are generated
test_copy_assignment.cpp: added test for multi_index_container allocator ctor
test_update.cpp: added test for stability of update functions wrt to unmodified keys

[SVN r46770]
2008-06-27 13:32:24 +00:00
Joaquín M López Muñoz 93da3b3f29 merged rev. 43157 from trunk
[SVN r43158]
2008-02-07 16:50:11 +00:00
Joaquín M López Muñoz 78f6bf5446 updated according to latest regression tests results, fixed a broken link, typo
[SVN r43157]
2008-02-07 16:29:27 +00:00
Joaquín M López Muñoz faf18a55f0 merged rev. 41397 from trunk
[SVN r41513]
2007-11-30 21:09:14 +00:00
Joaquín M López Muñoz aebc21ee44 ADL-based swap call moved to an utility function (after mistaken attempt at rev 41220 to solve name-hiding issues)
[SVN r41397]
2007-11-26 13:48:36 +00:00
Beman Dawes 0468378c0d Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes 9b4c07478c Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Joaquín M López Muñoz ff403f0a62 added .exe suffix missing at rev 41297
[SVN r41315]
2007-11-23 07:57:15 +00:00
Joaquín M López Muñoz efd8ea14ef included an exe filename modifying rule to avoid interference problems with Vista UAC (fixes #1429)
[SVN r41297]
2007-11-22 07:59:28 +00:00
Joaquín M López Muñoz 58fd64b622 moved some ADL stuff out of a potentially name-hiding scope
[SVN r41220]
2007-11-19 11:08:11 +00:00
Joaquín M López Muñoz f83aa3c780 updated according to latest regression tests results
[SVN r40838]
2007-11-06 14:33:59 +00:00
Joaquín M López Muñoz 26ce890ff8 fixed some struct/class discordances between decls and defs
[SVN r40542]
2007-10-29 08:16:56 +00:00
Joaquín M López Muñoz c4a9b8f8e6 updated according to latest regression tests results
[SVN r40541]
2007-10-29 08:12:58 +00:00
Joaquín M López Muñoz 3a4ac5c0a4 guarded some static asserts in project() funs from Sun C++ 5.7
[SVN r40292]
2007-10-22 17:22:46 +00:00
Joaquín M López Muñoz ae87c1d454 added missing #include
[SVN r40056]
2007-10-15 16:10:39 +00:00
Joaquín M López Muñoz 40634a5f23 typo
[SVN r40040]
2007-10-15 06:54:34 +00:00
Joaquín M López Muñoz 16778f3ff3 def_ctor_tuple_cons.hpp: no longer used
memfun_key.cpp: is now fun_key.cpp

[SVN r39923]
2007-10-11 11:23:47 +00:00
Joaquín M López Muñoz 47b172ab68 Boost 1.35 version of Boost.MultiIndex
allocator_utilities.hpp: added partial_std_allocator_wrapper::value_type
composite_key.hpp: used hash_fwd.hpp
auto_space.hpp: added support for non-standard allocators
bidir_node_iterator.hpp: moved friend-injected operators out of class
copy_map.hpp: added support for non-standard allocators
hash_index_args.hpp: removed deprecated use of <boost/functional/hash/hash.hpp>
hash_index_iterator.hpp: moved friend-injected operators our of class
hash_index_node.hpp: added support for non-standard allocators
header_holder.hpp:added support for non-standard allocators
index_base.hpp: added support for non-standard allocators, added modify_rollback, added small improvement to modify
index_loader.hpp: added support for non-standard allocators
index_matcher.hpp: added support for non-standard allocators
index_node_base.hpp: added support for non-standard allocators
iter_adaptor.hpp: added some out-of-class operators to alleviate a MSVC++ 6.0 problem
modify_key_adaptor.hpp: renamed some vars to accomudate broader usage scope
node_type.hpp: added support for non-standard allocators
ord_index_node.hpp: added support for non-standard allocators
ord_index_ops.hpp: implemented a more efficient equal_range
rnd_index_loader.hpp: added support for non-standard allocators
rnd_index_node.hpp: added support for non-standard allocators
rnd_index_ops.hpp: added support for non-standard allocators
rnd_index_ptr_array.hpp: added support for non-standard allocators
rnd_node_iterator.hpp: moved friend-injected operators out of class
seq_index_node.hpp: added support for non-standard allocators
seq_index_ops.hpp: added support for non-standard allocators
uintptr_type.hpp: added support for __int64
unbounded.hpp: fixed ODR problem
value_compare.hpp: fixed a small unefficiency
global_fun: initial commit
hashed_index.hpp: added support for non-standard allocators, added c[r]{begin|end}, [local_]iterator_to, rollback modify
identity_fwd.hpp: fixed wrong include guard name
key_extractors.hpp: added global_fun
mem_fun.hpp: removed superfluous =0's
ordered_index.hpp: added support for non-standard allocators, added c[r]{begin|end}, iterator_to, rollback modify, improved equal_range and range, added conformance to DR 233
random_access_index.hpp: added support for non-standard allocators, added c[r]{begin|end}, iterator_to, rollback modify, added conformance to 23.1.1/9
sequenced_index.hpp: added support for non-standard allocators, added c[r]{begin|end}, iterator_to, rollback modify, added conformance to 23.1.1/9, improved resize
multi_index_container.hpp: added support for non-standard allocators, improved ctor_args_list, rollback modify
acknowledgements.html: added entry for Boost 1.35
examples.html: renamed example 2, added B.IP example/composite_keys.cpp
future_work.html: removed entry on bimap
hash_indices.html: added c[r]{begin|end}, [local_]iterator_to, rollback modify
reference/index.html: added global_fun
reference/key_extraction.html: added global_fun, added technical correction
multi_index_container.html: added support for non-standard allocators
ord_indices.html: added c[r]{begin|end}, iterator_to, rollback modify
rnd_indices.html: added c[r]{begin|end}, iterator_to, rollback modify
seq_indices.html: added c[r]{begin|end}, iterator_to, rollback modify
release_notes.html: added entry for Boost 1.35
tests.html: added new serialization test file
basics.html: added rollback modify
creation.html: added support for non-standard allocators
tutorial/indices.html: added iterator_to
tutorial/key_extraction.html: added global_fun
composite_keys.cpp: fixed technicality
fun_key.cpp: was memfun_key.cpp, added global_fun
ip_allocator.cpp: initial commit
example/Jamfile.v2: renamed memfun_key, added ip_allocator
test_perf.cpp: fixed technicality
employee.hpp: used a non-standard allocator
test/Jamfile.v2: added new test file
non_std_allocator.hpp: initial commit
pair_of_ints.hpp: added decrement facilities
test_capacity.cpp: added extra check on resize
test_copy_assignment.cpp: added test for 23.1.1/9
test_iterators.cpp: added tests for c[r]{begin|end} and [local_]iterator_to, fixed technicality
test_key_extractors.cpp: added tests for global_fun
test_modifiers.cpp: added tests dor DR 233, fixed technicality
test_range.cpp: added extra checks to secure range refactoring
test_rearrange.cpp: fixed technicality
test_serialization.cpp: added new test file
test_serialization1.cpp: corrected include, used a non-standard allocator
test_serialization2.cpp: corrected include, used a non-standard allocator, split some stuff ro test_serialization3.cpp
test_serialization3.cpp: initial commit
test_serialization3.hpp: initial commit
test_serialization_template.hpp: removed some reliance on ADL
test_update.cpp: addes tests for rollback modify, fixed technicality

[SVN r39922]
2007-10-11 10:57:30 +00:00
Beman Dawes 1434c7d727 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody 33e19c4ce1 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Joaquín M. López Muñoz 47079d4620 merged from trunk to branch
[SVN r37105]
2007-02-27 07:49:12 +00:00
Joaquín M. López Muñoz d6932847ec fixed grammar
[SVN r37104]
2007-02-27 07:47:43 +00:00
Joaquín M. López Muñoz 543fbad471 merged from trunk to branch
[SVN r37079]
2007-02-26 09:16:36 +00:00
Joaquín M. López Muñoz 88a418d563 supressed GCC -W warnings about implicit initialization in copy ctors
[SVN r37078]
2007-02-26 09:13:50 +00:00
Joaquín M. López Muñoz 5d2015ed2e merged from trunk to branch
[SVN r37050]
2007-02-23 16:16:28 +00:00
Joaquín M. López Muñoz 16325e6039 supressed MSVC++ spurious C4312/C4311 warnings described at http://lists.boost.org/boost-users/2006/03/18075.php, with help from John Maddock
[SVN r37049]
2007-02-23 16:14:35 +00:00
Joaquín M. López Muñoz add267a90a merged from trunk to branch
[SVN r36776]
2007-01-24 18:21:23 +00:00
Joaquín M. López Muñoz 7be686f18e avoided reliance on template parameter array-to-pointer decay when calling std::equal since it was posing problems for ICC EM64T 9.1 over MSVC++ 8.0
[SVN r36775]
2007-01-24 18:19:32 +00:00
Joaquín M. López Muñoz de9febb387 merged from trunk to branch
[SVN r36480]
2006-12-21 12:01:02 +00:00
Joaquín M. López Muñoz 8bdf62586f fixed problem reported at http://lists.boost.org/boost-users/2006/12/24215.php
[SVN r36479]
2006-12-21 11:54:19 +00:00
Joaquín M. López Muñoz 6fa0f070b9 updated acknowledgements list
[SVN r36478]
2006-12-21 11:49:36 +00:00
Joaquín M. López Muñoz 1130b76e4b removed obsolete Boost.Build v1 Jamfile
[SVN r35903]
2006-11-07 14:51:19 +00:00
nobody 93d21ea64c This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35900]
2006-11-07 14:41:23 +00:00
Joaquín M. López Muñoz 2e22bed967 added v2 Jamfile
[SVN r35899]
2006-11-07 14:41:22 +00:00
Rene Rivera 28930f64c0 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Joaquín M. López Muñoz 6418bd5e83 merged from trunk to branch
[SVN r35634]
2006-10-16 17:40:23 +00:00
Joaquín M. López Muñoz 88f3a9ca8b added Sun Studio 11 for Solaris
[SVN r35633]
2006-10-16 17:37:04 +00:00
Joaquín M. López Muñoz 8e573eba2c extended coverage of BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS to Sun Studio
[SVN r35632]
2006-10-16 17:34:47 +00:00
Joaquín M. López Muñoz e46279d9ec merged from trunk to branch
[SVN r35444]
2006-10-02 15:20:03 +00:00
Joaquín M. López Muñoz 2e361f8b6a updated acknowledgements list
[SVN r35441]
2006-10-02 15:13:57 +00:00
Joaquín M. López Muñoz 259f87b550 fixed bugs reported at http://lists.boost.org/boost-users/2006/09/22604.php
[SVN r35440]
2006-10-02 15:12:46 +00:00
Joaquín M. López Muñoz 99284aa1c5 merged from trunk to branch
[SVN r34743]
2006-07-26 15:12:41 +00:00
Joaquín M. López Muñoz bbeb058580 updated according to latest regression tests results
[SVN r34742]
2006-07-26 15:09:41 +00:00
Joaquín M. López Muñoz 5cd33a9a81 updated acknowledgements list
[SVN r34741]
2006-07-26 14:56:57 +00:00
Joaquín M. López Muñoz c41ded0890 merged from trunk to branch
[SVN r34604]
2006-07-20 06:19:59 +00:00
Joaquín M. López Muñoz 252398ac13 added missing include
[SVN r34603]
2006-07-20 06:18:53 +00:00
Joaquín M. López Muñoz 0c0acfaa3f merged from trunk to branch
[SVN r34527]
2006-07-13 07:57:18 +00:00
Joaquín M. López Muñoz 64b5247bea typo
[SVN r34525]
2006-07-13 07:49:46 +00:00
Joaquín M. López Muñoz bcec2c0467 replaced some &'s with &amp;'s
[SVN r34524]
2006-07-13 07:48:49 +00:00
Joaquín M. López Muñoz c6e0231bed typos
[SVN r34523]
2006-07-13 07:46:19 +00:00
Joaquín M. López Muñoz c757629a6d updated dead link
[SVN r34522]
2006-07-13 07:45:28 +00:00
Joaquín M. López Muñoz 5c5ca84a23 merged from trunk to branch
[SVN r34022]
2006-05-19 06:57:13 +00:00
Joaquín M. López Muñoz 14d94f24fa added names of bug reporters
[SVN r34021]
2006-05-19 06:52:29 +00:00
Joaquín M. López Muñoz 18c8724a46 fixed bug reported at http://lists.boost.org/boost-users/2006/05/19362.php
[SVN r34020]
2006-05-19 06:51:20 +00:00
Joaquín M. López Muñoz 5f0ac92335 fixed some compiler version numbers
[SVN r34019]
2006-05-19 06:49:21 +00:00
Joaquín M. López Muñoz c8e707ddd7 avoided ctor arguments with the same name as correspondent members, as some compilers seem to choke on X::X(T t):t(t)
[SVN r34018]
2006-05-19 06:48:22 +00:00
Joaquín M. López Muñoz 48764f7801 merged from trunk to branch
[SVN r33915]
2006-05-03 09:30:45 +00:00
Joaquín M. López Muñoz f7d22b4de3 rewritten erase(key) to avoid implicit iterator increments leading to linear complexity, as reported by Guillaume Lazzara
[SVN r33914]
2006-05-03 09:28:08 +00:00
Joaquín M. López Muñoz f91af5453c merged from trunk to branch
[SVN r33760]
2006-04-21 13:09:37 +00:00
Joaquín M. López Muñoz c16d49acd0 omitted unused arg names
[SVN r33759]
2006-04-21 13:07:41 +00:00
Joaquín M. López Muñoz 87383bcc10 merged from trunk to branch
[SVN r33742]
2006-04-19 07:23:16 +00:00
Joaquín M. López Muñoz 28192c181a bitten by 8.5.3/5
[SVN r33741]
2006-04-19 07:16:21 +00:00
Joaquín M. López Muñoz d7f2c3606b merged from trunk to branch
[SVN r33734]
2006-04-18 17:01:51 +00:00
Joaquín M. López Muñoz 444ebbe95b fixed key extraction problems with non-copyable classes reported at http://lists.boost.org/Archives/boost/2006/04/103065.php; added missing '&'
[SVN r33733]
2006-04-18 16:33:51 +00:00
Joaquín M. López Muñoz 5ecebcbc78 fixed key extraction problems with non-copyable classes reported at http://lists.boost.org/Archives/boost/2006/04/103065.php
[SVN r33732]
2006-04-18 16:32:42 +00:00
Joaquín M. López Muñoz 3a663bd7c4 merged from trunk to branch
[SVN r33545]
2006-04-05 07:28:50 +00:00
Joaquín M. López Muñoz 9a782276a4 fixed doppelganger bug of that discovered for STLport at http://lists.boost.org/Archives/boost/2006/04/102740.php
[SVN r33544]
2006-04-05 07:21:58 +00:00
Joaquín M. López Muñoz f86dce9db1 corrected complexity bound
[SVN r33543]
2006-04-05 07:15:54 +00:00
Joaquín M. López Muñoz 37ac7c0377 merged from trunk to branch
[SVN r33430]
2006-03-22 07:25:04 +00:00
Joaquín M. López Muñoz 2448ba2a95 removed private ctor decls so that nodes are trivially constructible
[SVN r33429]
2006-03-22 07:16:44 +00:00
nobody 75de04b6f8 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
Joaquín M. López Muñoz 8ecbfdf080 added fix for a bug of CW 8.3 in "ISO C++ Template Parser" mode causing bogus safe mode run-time asserts
[SVN r33314]
2006-03-10 15:23:42 +00:00
Joaquín M. López Muñoz f9c9851ef3 added workaround for CW 8.3
[SVN r33313]
2006-03-10 15:19:52 +00:00
Joaquín M. López Muñoz 708f8bd4ab sync with v1 Jamfile
[SVN r33256]
2006-03-07 13:17:59 +00:00
Joaquín M. López Muñoz c21722cd10 added blanks to prevent buggy preprocessors from parsing two '>'s as a '>>'
[SVN r33225]
2006-03-06 07:27:05 +00:00
Joaquín M. López Muñoz db3889ceff missing word
[SVN r33206]
2006-03-03 07:20:11 +00:00
Joaquín M. López Muñoz 3be7ae350e typo
[SVN r33201]
2006-03-02 16:17:28 +00:00
Joaquín M. López Muñoz 2a6813f2e7 split test_serialization into two files to reduce stress on MSVC 7.0
[SVN r33200]
2006-03-02 16:14:01 +00:00
Joaquín M. López Muñoz 842bc1ba70 split test_serialization into two to reduce stress on MSVC 7.0
[SVN r33199]
2006-03-02 16:14:00 +00:00
Joaquín M. López Muñoz a1944a19a2 extended workaround from MSVC 6.0 to 7.0
[SVN r33142]
2006-02-27 14:06:06 +00:00
Joaquín M. López Muñoz c2d7a65cfd lexical error
[SVN r33050]
2006-02-21 07:18:14 +00:00
Joaquín M. López Muñoz cf84a0dc1c fixed bug reported at http://lists.boost.org/boost-users/2006/02/17230.php
[SVN r32966]
2006-02-16 16:02:25 +00:00
Joaquín M. López Muñoz 5fec019715 fixed seemingly illegal ADL usage as per std 14.6.4.2
[SVN r32746]
2006-02-08 17:37:33 +00:00
Vladimir Prus c7bfd7cf83 Update Jamfile.v2
[SVN r32735]
2006-02-08 13:26:10 +00:00
Joaquín M. López Muñoz 1235106ac0 merged into test_rearrange
[SVN r32674]
2006-02-06 16:27:33 +00:00
Joaquín M. López Muñoz 5e790014c1 restructured into several pages under doc/tutorial/
[SVN r32673]
2006-02-06 16:14:05 +00:00
Joaquín M. López Muñoz a9c89540ac moved to doc/tutorial/multi_index_cont_example.png
[SVN r32672]
2006-02-06 16:12:58 +00:00
Joaquín M. López Muñoz 1fc02c6b1d removed as parts of the old safe mode framework
[SVN r32671]
2006-02-06 16:08:18 +00:00
Joaquín M. López Muñoz f54edbf0d3 added random access indices; out of bounds checking
[SVN r32670]
2006-02-06 15:53:36 +00:00
Joaquín M. López Muñoz 7274eca56c added random access indices
[SVN r32669]
2006-02-06 15:52:21 +00:00
Joaquín M. López Muñoz e953c2b4ff restricted acceptance of chained pointers so as to not mask convertibility to Value
[SVN r32668]
2006-02-06 15:50:58 +00:00
Joaquín M. López Muñoz cf076474d2 overloaded composite_key_compare::operator() to treat non-tuples as tuples of length 1
[SVN r32667]
2006-02-06 15:48:53 +00:00
Joaquín M. López Muñoz 4c7a97e890 removed test_special_list_ops; added test_rearrange
[SVN r32666]
2006-02-06 15:46:21 +00:00
Joaquín M. López Muñoz 10fe2cd1ab added random access indices; used some type hiding
[SVN r32665]
2006-02-06 15:45:42 +00:00
Joaquín M. López Muñoz b81ee48320 extended test period to increase robustness; considered __GLIBCXX__ for node size calculations
[SVN r32664]
2006-02-06 15:43:36 +00:00
Joaquín M. López Muñoz e043cadb7c added random_access and rearrange
[SVN r32663]
2006-02-06 15:41:56 +00:00
Joaquín M. López Muñoz 233fd40984 removed test_special_list_ops; added test_rearrange; added navigational <link>s;
[SVN r32662]
2006-02-06 15:41:00 +00:00
Joaquín M. López Muñoz 67c04d598f updated; added navigational <link>s
[SVN r32661]
2006-02-06 15:39:35 +00:00
Joaquín M. López Muñoz f1dde3d84e added rearrange facilities; added navigational <link>s; typos
[SVN r32660]
2006-02-06 15:38:39 +00:00
Joaquín M. López Muñoz f8eb1b16ce added navigational <link>s
[SVN r32659]
2006-02-06 15:36:55 +00:00
Joaquín M. López Muñoz 119d6d4a1c restricted acceptance of chained pointers so as to not mask convertibility to Value; overloaded composite_key_compare::operator() to treat non-tuples as tuples of length 1; added navigational <link>s
[SVN r32658]
2006-02-06 15:35:31 +00:00
Joaquín M. López Muñoz 8682a33fcb new section on index views; added navigational <link>s
[SVN r32657]
2006-02-06 15:33:56 +00:00
Joaquín M. López Muñoz 34da3c9fd5 added random access indices; added navigational <link>s
[SVN r32656]
2006-02-06 15:32:27 +00:00
Joaquín M. López Muñoz 0bacd6fbed updated performance figures; discussed ordered index nodes compression; added navigational <link>s
[SVN r32655]
2006-02-06 15:30:50 +00:00
Joaquín M. López Muñoz 98d4cea748 updated performance figures
[SVN r32653]
2006-02-06 15:24:25 +00:00
Joaquín M. López Muñoz a872178185 some link adjustment; added navigational <link>s
[SVN r32652]
2006-02-06 15:22:34 +00:00
Joaquín M. López Muñoz 027b5105ac removed the part on random access indices (already implemented); added navigational <link>s
[SVN r32651]
2006-02-06 15:21:34 +00:00
Joaquín M. López Muñoz d18e3fd6a5 new examples for random access indices and rearrange facilities; added navigational <link>s
[SVN r32650]
2006-02-06 15:20:23 +00:00
Joaquín M. López Muñoz ae533e1b16 noted limitations due to lack of SFINAE and function template ordering support; added navigational <link>s
[SVN r32649]
2006-02-06 15:19:25 +00:00
Joaquín M. López Muñoz 4f6d05b115 added acknowledgements for 1.34 release; added navigational <link>s
[SVN r32647]
2006-02-06 15:17:11 +00:00
Joaquín M. López Muñoz 1e39e5f9af added rearrange facilities
[SVN r32645]
2006-02-06 15:15:45 +00:00
Joaquín M. López Muñoz c1f8fc6348 added random access indices
[SVN r32644]
2006-02-06 15:14:51 +00:00
Joaquín M. López Muñoz f1dcc889ec coming from doc/advanced_topics.html
[SVN r32643]
2006-02-06 15:13:18 +00:00
Joaquín M. López Muñoz 1669a1fb2d moved from doc/multi_index_cont_example.png
[SVN r32642]
2006-02-06 15:12:21 +00:00
Joaquín M. López Muñoz 5fd646dc67 coming from doc/advanced_topics.html; new sections on key extraction concepts and predefined key extractors
[SVN r32641]
2006-02-06 15:10:56 +00:00
Joaquín M. López Muñoz ac2a6d72a3 coming from doc/advanced_topics.html; new sections on index classification, random access indices, index rearranging and ordered indices node compression
[SVN r32640]
2006-02-06 15:09:06 +00:00
Joaquín M. López Muñoz 8d3cfd51a8 coming from doc/tutorial.html
[SVN r32639]
2006-02-06 15:07:46 +00:00
Joaquín M. López Muñoz 35a151c9b0 coming from doc/advanced_topics.html
[SVN r32638]
2006-02-06 15:06:06 +00:00
Joaquín M. López Muñoz aa0ef9b10c coming from doc/advanced_topics.html; new section on value semantics
[SVN r32637]
2006-02-06 15:05:19 +00:00
Joaquín M. López Muñoz cc3da5b51c new member in the family
[SVN r32636]
2006-02-06 15:02:04 +00:00
Joaquín M. López Muñoz 83a1b490ea unsigned integral type with the same size as void *
[SVN r32635]
2006-02-06 15:01:26 +00:00
Joaquín M. López Muñoz 12b9ac21c4 helper class to help reduce symbol name lenghts when using safe mode in MSVC 6.0
[SVN r32634]
2006-02-06 15:00:14 +00:00
Joaquín M. López Muñoz 5190a31109 generic iterator for random access indices
[SVN r32633]
2006-02-06 14:58:46 +00:00
Joaquín M. López Muñoz 192d43569b internal version of boost::iterator_adaptor with better compile times
[SVN r32632]
2006-02-06 14:57:31 +00:00
Joaquín M. López Muñoz aa5cfdfb3c added random access indices
[SVN r32631]
2006-02-06 14:56:21 +00:00
Joaquín M. López Muñoz 519d96871f generic iterator for bidirectional indices
[SVN r32630]
2006-02-06 14:52:08 +00:00
Joaquín M. López Muñoz 9c61f94492 MSVC 6.0 workaround for index_type_list; node values are now accessed through a memfun
[SVN r32629]
2006-02-06 14:49:58 +00:00
Joaquín M. López Muñoz dd5a6bd9a4 adapted to new safe mode framework; node values are now accessed through a memfun; new rearrange memfun; tiny optimization
[SVN r32628]
2006-02-06 14:48:22 +00:00
Joaquín M. López Muñoz 37ca90b823 out of bounds checking
[SVN r32627]
2006-02-06 14:46:03 +00:00
Joaquín M. López Muñoz 964d83df51 adapted to new safe mode framework; rewritten insert_ and link memfuns so as to avoid trycatches; new restore algorithm; node values are now accessed through a memfun
[SVN r32626]
2006-02-06 14:45:15 +00:00
Joaquín M. López Muñoz b16c15342a restricted acceptance of chained pointers so as to not mask convertibility to Value
[SVN r32625]
2006-02-06 14:40:49 +00:00
Joaquín M. López Muñoz e636c5ec72 adapted to new safe mode framework; node values are now accessed through a memfun
[SVN r32624]
2006-02-06 14:39:05 +00:00
Joaquín M. López Muñoz 1654aaa24e missing const qualifier
[SVN r32623]
2006-02-06 14:37:39 +00:00
Joaquín M. López Muñoz 4797a93e7b tweaked previous fix for MSVC 6.0
[SVN r32622]
2006-02-06 14:36:33 +00:00
Joaquín M. López Muñoz 41d3f814ba used aligned_storage according to TR1 interface
[SVN r32621]
2006-02-06 14:35:05 +00:00
Joaquín M. López Muñoz 5aa6cc3b03 removed interoperability bits with old safe mode framework; tiny optimization
[SVN r32620]
2006-02-06 14:34:00 +00:00
Joaquín M. López Muñoz 2cdc3c3778 new safe mode framework based on iterator adaption rather than derivation from safe_iterator; out of bounds checking
[SVN r32619]
2006-02-06 14:32:44 +00:00
Joaquín M. López Muñoz f30144473d node values are now accessed through a memfun
[SVN r32618]
2006-02-06 14:28:14 +00:00
Joaquín M. López Muñoz 7a6121fbbf implemented spatial compression technique; adapted to new safe mode framework; new restore algorithm; tiny optimization
[SVN r32617]
2006-02-06 14:27:26 +00:00
Joaquín M. López Muñoz 538977752f used POD and TR1 guarantees to make node* obtainable from value_type*; node values are now accessed through a memfun
[SVN r32616]
2006-02-06 14:23:02 +00:00
Joaquín M. López Muñoz 2d346be3fb node values are now accessed through a memfun
[SVN r32615]
2006-02-06 14:20:39 +00:00
Joaquín M. López Muñoz 405e8b2a53 refactored to not use base_from_member
[SVN r32614]
2006-02-06 14:19:49 +00:00
Joaquín M. López Muñoz 9ca897dae2 removed interoperability bits with old safe mode framework; tiny optimization
[SVN r32613]
2006-02-06 14:18:45 +00:00
Joaquín M. López Muñoz 683ab3be1d removed interoperability bits with old safe mode framework
[SVN r32612]
2006-02-06 14:17:29 +00:00
Joaquín M. López Muñoz aa4edd99cf fixed error in sync() (http://lists.boost.org/boost-users/2006/01/16710.php); fixed some other inconsistencies
[SVN r32611]
2006-02-06 14:14:28 +00:00
Joaquín M. López Muñoz a87b1eea96 node values are now accessed through a memfun
[SVN r32610]
2006-02-06 14:11:52 +00:00
Joaquín M. López Muñoz 3c1395a626 renamed some identifiers according to newest semantics
[SVN r32609]
2006-02-06 14:09:49 +00:00
Joaquín M. López Muñoz 80812e471a added get_allocator
[SVN r32608]
2006-02-06 14:07:29 +00:00
Joaquín M. López Muñoz edd622e5ac used aligned_storage according to TR1 interface
[SVN r32607]
2006-02-06 14:06:20 +00:00
Joaquín M. López Muñoz 4db9b44b75 in composite_key()::operator(), restricted acceptance of chained pointers so as to not mask convertibility to Value; overloaded composite_key_compare::operator() to treat non-tuples as tuples of length 1
[SVN r32606]
2006-02-06 14:03:55 +00:00
Joaquín M. López Muñoz c6a1c3dd92 fixed SF bug #1378025 (https://sourceforge.net/tracker/?func=detail&atid=107586&aid=1378025&group_id=7586), solution ripped from http://mail.python.org/pipermail/c++-sig/2003-October/005986.html
[SVN r32003]
2005-12-12 17:27:12 +00:00
Joaquín M. López Muñoz 7aacfe029e merged from Version_1_33_1
[SVN r31994]
2005-12-12 08:11:55 +00:00
Joaquín M. López Muñoz 1361bfe530 updated; changes meant for 1.34 are included in 1.33.1
[SVN r30812]
2005-09-05 08:40:38 +00:00
Joaquín M. López Muñoz b92f05140b typos and formatting
[SVN r30811]
2005-09-05 08:39:00 +00:00
Joaquín M. López Muñoz 95d44a6109 fixed a call to reset_object_address (previous version did work, though)
[SVN r30810]
2005-09-05 08:37:35 +00:00
Joaquín M. López Muñoz c7f63a348f removed some of the previous locks as they don't apply to the protected use cases
[SVN r30809]
2005-09-05 08:34:29 +00:00
Joaquín M. López Muñoz f1ad358bff fixed an invariant unsafe flow path
[SVN r30767]
2005-09-01 08:00:57 +00:00
Joaquín M. López Muñoz cfa63b8a4c made safe mode iterators mutithread-safe
[SVN r30750]
2005-08-31 13:50:32 +00:00
Joaquín M. López Muñoz 41be013bc6 updated
[SVN r30723]
2005-08-29 11:53:14 +00:00
Joaquín M. López Muñoz 1e00c5139b erase(position) and erase(first,last) now return iterator to following element
[SVN r30722]
2005-08-29 11:51:56 +00:00
Joaquín M. López Muñoz b3de839dee updated link to TR1 doc; erase(position) and erase(first,last) now return iterator to following element
[SVN r30721]
2005-08-29 11:51:18 +00:00
Joaquín M. López Muñoz 18234ebeee updated link to TR1 doc
[SVN r30720]
2005-08-29 11:50:18 +00:00
Joaquín M. López Muñoz 92207dde6a erase(position) and erase(first,last) for ordered and hashed indices now return iterator to following element
[SVN r30719]
2005-08-29 11:48:20 +00:00
Joaquín M. López Muñoz 7343ddf980 added statement about iterator/reference stability
[SVN r30621]
2005-08-22 08:39:25 +00:00
Joaquín M. López Muñoz 434680c817 typo
[SVN r30620]
2005-08-22 08:18:13 +00:00
Douglas Gregor b28164d7f8 Merged from 1.33.0 release
[SVN r30540]
2005-08-12 13:02:37 +00:00
255 changed files with 31227 additions and 11221 deletions
+486
View File
@@ -0,0 +1,486 @@
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
local library = "multi_index";
local triggers =
{
branch: [ "master", "develop", "feature/*", "fix/*" ]
};
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
local asan = { ASAN: '1' };
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "linux",
arch: arch
},
steps:
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'set -e',
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
] +
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "exec",
trigger: triggers,
platform: {
"os": "darwin",
"arch": arch
},
node: {
"os": osx_version
},
steps: [
{
name: "everything",
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
commands:
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local windows_pipeline(name, image, environment, arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "windows",
arch: arch
},
"steps":
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'cmd /C .drone\\\\drone.bat ' + library,
]
}
]
};
[
linux_pipeline(
"Linux 14.04 GCC 4.8* 32/64",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 14.04 GCC 4.9 32/64",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11', ADDRMD: '32,64' },
"g++-4.9-multilib",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 16.04 GCC 5* 32/64",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 18.04 GCC 6 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '11,14', ADDRMD: '32,64' },
"g++-6-multilib",
),
linux_pipeline(
"Linux 18.04 GCC 7* 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 18.04 GCC 8 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '11,14,17', ADDRMD: '32,64' },
"g++-8-multilib",
),
linux_pipeline(
"Linux 20.04 GCC 9* 32/64",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 20.04 GCC 9* ARM64",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' },
arch="arm64",
),
linux_pipeline(
"Linux 20.04 GCC 9* S390x",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' },
arch="s390x",
),
linux_pipeline(
"Linux 20.04 GCC 10 32/64",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14,17,20', ADDRMD: '32,64' },
"g++-10-multilib",
),
linux_pipeline(
"Linux 22.04 GCC 11* 32/64",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 22.04 GCC 12 32/64 C++11-14",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11,14', ADDRMD: '32,64' },
"g++-12-multilib",
),
linux_pipeline(
"Linux 22.04 GCC 12 32/64 C++17-20",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '17,20', ADDRMD: '32,64' },
"g++-12-multilib",
),
linux_pipeline(
"Linux 22.04 GCC 12 32/64",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '2b', ADDRMD: '32,64' },
"g++-12-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32/64 UBSAN C++11-14",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14', ADDRMD: '32,64' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32/64 UBSAN C++17-20",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '17,20', ADDRMD: '32,64' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32/64 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '2b', ADDRMD: '32,64' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32 ASAN C++11-14",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14', ADDRMD: '32' } + asan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32 ASAN C++17-20",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '17,20', ADDRMD: '32' } + asan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '2b', ADDRMD: '32' } + asan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 UBSAN C++11-14",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 UBSAN C++17-20",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '17,20' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '2b' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 ASAN C++11-14",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 ASAN C++17-20",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '17,20' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '2b' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 16.04 Clang 3.5",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '11' },
"clang-3.5",
),
linux_pipeline(
"Linux 16.04 Clang 3.6",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '11,14' },
"clang-3.6",
),
linux_pipeline(
"Linux 16.04 Clang 3.7",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '11,14' },
"clang-3.7",
),
linux_pipeline(
"Linux 16.04 Clang 3.8",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '11,14' },
"clang-3.8",
),
linux_pipeline(
"Linux 18.04 Clang 3.9",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.9', CXXSTD: '11,14' },
"clang-3.9",
),
linux_pipeline(
"Linux 18.04 Clang 4.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-4.0', CXXSTD: '11,14' },
"clang-4.0",
),
linux_pipeline(
"Linux 18.04 Clang 5.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '11,14' },
"clang-5.0",
),
linux_pipeline(
"Linux 18.04 Clang 6.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-6.0', CXXSTD: '11,14,17' },
"clang-6.0",
),
linux_pipeline(
"Linux 20.04 Clang 7",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '11,14,17' },
"clang-7",
),
linux_pipeline(
"Linux 20.04 Clang 8",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '11,14,17' },
"clang-8",
),
linux_pipeline(
"Linux 20.04 Clang 9",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '11,14,17,2a' },
"clang-9",
),
linux_pipeline(
"Linux 20.04 Clang 10",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '11,14,17,2a' },
"clang-10",
),
linux_pipeline(
"Linux 20.04 Clang 11",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '11,14,17,2a' },
"clang-11",
),
linux_pipeline(
"Linux 20.04 Clang 12",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '11,14,17,2a' },
"clang-12",
),
linux_pipeline(
"Linux 22.04 Clang 13",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '11,14,17,20' },
"clang-13",
),
linux_pipeline(
"Linux 22.04 Clang 14",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14,17,20,2b' },
"clang-14",
),
linux_pipeline(
"Linux 22.04 Clang 15",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '11,14,17,20,2b' },
"clang-15",
),
linux_pipeline(
"Linux 23.04 Clang 16",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '11,14,17,20,2b' },
"clang-16",
),
linux_pipeline(
"Linux 23.10 Clang 17 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + ubsan,
"clang-17",
),
linux_pipeline(
"Linux 23.10 Clang 17 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + asan,
"clang-17",
),
linux_pipeline(
"Linux 24.04 Clang 18 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + ubsan,
"clang-18",
),
linux_pipeline(
"Linux 24.04 Clang 18 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + asan,
"clang-18",
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 UBSAN (11,14)",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14' } + ubsan,
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 UBSAN (17,2a)",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '17,2a' } + ubsan,
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 ASAN (11,14)",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14' } + asan,
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 ASAN (17,2a)",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '17,2a' } + asan,
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b', LINK: 'static' } + ubsan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + asan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
windows_pipeline(
"Windows VS2015 msvc-14.0",
"cppalliance/dronevs2015",
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', B2_DONT_EMBED_MANIFEST: '1' },
),
windows_pipeline(
"Windows VS2017 msvc-14.1",
"cppalliance/dronevs2017",
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
),
windows_pipeline(
"Windows VS2019 msvc-14.2",
"cppalliance/dronevs2019",
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' },
),
windows_pipeline(
"Windows VS2022 msvc-14.3",
"cppalliance/dronevs2022:1",
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' },
),
]
+23
View File
@@ -0,0 +1,23 @@
@REM Copyright 2022 Peter Dimov
@REM Distributed under the Boost Software License, Version 1.0.
@REM https://www.boost.org/LICENSE_1_0.txt
@ECHO ON
set LIBRARY=%1
set DRONE_BUILD_DIR=%CD%
set BOOST_BRANCH=develop
if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init tools/boostdep
xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\
python tools/boostdep/depinst/depinst.py -I examples %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
set -ex
export PATH=~/.local/bin:/usr/local/bin:$PATH
DRONE_BUILD_DIR=$(pwd)
BOOST_BRANCH=develop
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init tools/boostdep
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py -I examples $LIBRARY
./bootstrap.sh
./b2 -d0 headers
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} ${LINK:+link=$LINK}
+325
View File
@@ -0,0 +1,325 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
- fix/**
env:
UBSAN_OPTIONS: print_stacktrace=1
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-4.8
cxxstd: "11"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-4.8-multilib
address-model: 32,64
- toolset: gcc-5
cxxstd: "11,14,1z"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-5-multilib
address-model: 32,64
- toolset: gcc-6
cxxstd: "11,14,1z"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-6-multilib
address-model: 32,64
- toolset: gcc-7
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-7-multilib
address-model: 32,64
- toolset: gcc-8
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-8-multilib
address-model: 32,64
- toolset: gcc-9
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-9-multilib
address-model: 32,64
- toolset: gcc-10
cxxstd: "11,14,17,2a"
os: ubuntu-22.04
install: g++-10-multilib
address-model: 32,64
- toolset: gcc-11
cxxstd: "11,14,17,20"
os: ubuntu-22.04
install: g++-11-multilib
address-model: 32,64
- toolset: gcc-12
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: g++-12-multilib
address-model: 32,64
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-24.04
install: g++-13-multilib
address-model: 32,64
- toolset: gcc-14
cxxstd: "11,14,17,20,2b"
os: ubuntu-24.04
install: g++-14-multilib
address-model: 32,64
- toolset: gcc-15
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:26.04
os: ubuntu-latest
install: g++-15-multilib
address-model: 32,64
- toolset: gcc-16
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:26.04
os: ubuntu-latest
install: g++-16-multilib
address-model: 32,64
- toolset: clang
compiler: clang++-3.9
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,20"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-12
- toolset: clang
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-16
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-17
- toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-18
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-19
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-20
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "11,14,17,20,23,2c"
os: macos-15
- toolset: clang
cxxstd: "11,14,17,20,23,2c"
os: macos-26
runs-on: ${{matrix.os}}
container:
image: ${{matrix.container}}
volumes:
- /node20217:/node20217:rw,rshared
- ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }}
defaults:
run:
shell: bash
steps:
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++ curl xz-utils
if [[ "${{matrix.container}}" == "ubuntu:1"* ]]; then
# Node 20 doesn't work with Ubuntu 16/18 glibc: https://github.com/actions/checkout/issues/1590
curl -sL https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz | tar -xJ --strip-components 1 -C /node20217
fi
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: |
sudo apt-get update
sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python3 tools/boostdep/depinst/depinst.py -I example --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
export ADDRMD=${{matrix.address-model}}
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py -I example --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
+275
View File
@@ -0,0 +1,275 @@
# Copyright 2003-2019 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.
sudo: false
language: cpp
os: linux
dist: trusty
branches:
only:
- develop
- master
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude: # workaround for https://github.com/travis-ci/travis-ci/issues/4681
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
- os: linux
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.3
- os: linux
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.4
- os: linux
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- os: linux
compiler: clang++-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- os: linux
compiler: clang++-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- os: linux
compiler: clang++-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
- os: linux
compiler: clang++-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7
- os: linux
compiler: clang++-7
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-7
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7
- os: linux
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
addons:
apt:
packages:
- libc++-dev
- os: linux
compiler: clang++-libc++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
install:
- cd ..
- git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init
- git rm --ignore-unmatch libs/multi_index/
- ./bootstrap.sh
- ./b2 headers
- mkdir libs/multi_index
- cp -r $TRAVIS_BUILD_DIR/* libs/multi_index
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- ./b2 libs/multi_index/test toolset=$TOOLSET cxxstd=$CXXSTD
+38
View File
@@ -0,0 +1,38 @@
# Generated by `boostdep --cmake multi_index`
# Copyright 2020 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.8...3.16)
project(boost_multi_index VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_multi_index INTERFACE)
add_library(Boost::multi_index ALIAS boost_multi_index)
target_compile_features(boost_multi_index INTERFACE cxx_std_11)
target_include_directories(boost_multi_index INTERFACE include)
target_link_libraries(boost_multi_index
INTERFACE
Boost::assert
Boost::bind
Boost::config
Boost::container_hash
Boost::core
Boost::integer
Boost::mp11
Boost::preprocessor
Boost::smart_ptr
Boost::throw_exception
Boost::tuple
Boost::type_traits
Boost::utility
)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()
-16
View File
@@ -1,16 +0,0 @@
# Boost.MultiIndex examples and tests Jamfile
#
# Copyright 2003-2004 Joaquín M López Muñoz.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
#
# See http://www.boost.org/libs/multi_index for library home page.
subproject libs/multi_index ;
# please order by name to ease maintenance
subinclude libs/multi_index/example ;
subinclude libs/multi_index/test ;
subinclude libs/multi_index/perf ;
+48
View File
@@ -0,0 +1,48 @@
# Boost Multi-index Containers Library
[![Branch](https://img.shields.io/badge/branch-master-brightgreen.svg)](https://github.com/boostorg/multi_index/tree/master) [![CI](https://github.com/boostorg/multi_index/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/multi_index/actions/workflows/ci.yml) [![Drone status](https://img.shields.io/drone/build/boostorg/multi_index/master?server=https%3A%2F%2Fdrone.cpp.al&logo=drone&logoColor=%23CCCCCC&label=CI)](https://drone.cpp.al/boostorg/multi_index) [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/multi_index.html) [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/multi_index) [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://regression.boost.org/master/developer/multi_index.html)<br/>
[![Branch](https://img.shields.io/badge/branch-develop-brightgreen.svg)](https://github.com/boostorg/multi_index/tree/develop) [![CI](https://github.com/boostorg/multi_index/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/multi_index/actions/workflows/ci.yml) [![Drone status](https://img.shields.io/drone/build/boostorg/multi_index/develop?server=https%3A%2F%2Fdrone.cpp.al&logo=drone&logoColor=%23CCCCCC&label=CI)](https://drone.cpp.al/boostorg/multi_index) [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/multi_index.html) [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/multi_index) [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://regression.boost.org/develop/developer/multi_index.html)<br/>
[![BSL 1.0](https://img.shields.io/badge/license-BSL_1.0-blue.svg)](https://www.boost.org/users/license.html) <img alt="C++11 required" src="https://img.shields.io/badge/standard-C%2b%2b11-blue.svg"> <img alt="Header-only library" src="https://img.shields.io/badge/build-header--only-blue.svg">
[Boost.MultiIndex](http://boost.org/libs/multi_index) provides a class template
named `multi_index_container` which enables the construction of containers
maintaining one or more indices with different sorting and access semantics.
## Learn about Boost.MultiIndex
* [Online documentation](https://boost.org/libs/multi_index)
## Install Boost.MultiIndex
* [Download Boost](https://www.boost.org/users/download/) and you're ready to go (this is a header-only library requiring no building).
* Using Conan 2: In case you don't have it yet, add an entry for Boost in your `conanfile.txt` (the example requires at least Boost 1.86):
```
[requires]
boost/[>=1.86.0]
```
<ul>If you're not using any compiled Boost library, the following will skip building altogether:</ul>
```
[options]
boost:header_only=True
```
* Using vcpkg: Execute the command
```
vcpkg install boost-multi-index
```
* Using CMake: [Boost CMake support infrastructure](https://github.com/boostorg/cmake)
allows you to use CMake directly to download, build and consume all of Boost or
some specific libraries.
## Support
* Join the **#boost** discussion group at [cpplang.slack.com](https://cpplang.slack.com/)
([ask for an invite](https://cppalliance.org/slack/) if youre not a member of this workspace yet)
* Ask in the [Boost Users mailing list](https://lists.boost.org/mailman/listinfo.cgi/boost-users)
(add the `[multi_index]` tag at the beginning of the subject line)
* [File an issue](https://github.com/boostorg/multi_index/issues)
## Contribute
* [Pull requests](https://github.com/boostorg/multi_index/pulls) against **develop** branch are most welcome.
Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+37
View File
@@ -0,0 +1,37 @@
# Copyright 2003-2021 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.
version: 1.0.{build}-{branch}
branches:
only:
- master
- develop
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
install:
- cd ..
- git clone -b %APPVEYOR_REPO_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init
- git rm --ignore-unmatch libs/multi_index/
- bootstrap
- b2 headers
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\multi_index\
build: off
test_script:
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- b2 address-model=32 libs/multi_index/test toolset=%TOOLSET% %CXXSTD%
+35
View File
@@ -0,0 +1,35 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# 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)
require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/bind//boost_bind
/boost/config//boost_config
/boost/container_hash//boost_container_hash
/boost/core//boost_core
/boost/integer//boost_integer
/boost/mp11//boost_mp11
/boost/preprocessor//boost_preprocessor
/boost/smart_ptr//boost_smart_ptr
/boost/throw_exception//boost_throw_exception
/boost/tuple//boost_tuple
/boost/type_traits//boost_type_traits
/boost/utility//boost_utility ;
project /boost/multi_index
: common-requirements
<include>include
;
explicit
[ alias boost_multi_index : : : : <library>$(boost_dependencies) ]
[ alias all : boost_multi_index example perf test ]
;
call-if : boost-library multi_index
;
+64 -3
View File
@@ -5,6 +5,9 @@
<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">
<link rel="start" href="index.html">
<link rel="prev" href="release_notes.html">
<link rel="up" href="index.html">
</head>
<body>
@@ -94,7 +97,7 @@ purpose. It is provided &quot;as is&quot; without express or implied warranty.
</blockquote>
<p>
<span style="float:right;"><img src="lopez.jpg" width="160" height="120"></span>
<span style="float:right;margin-left:10px"><img src="lopez.jpg" width="160" height="120"></span>
I would like to dedicate this piece of work to Rosa Bern&aacute;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&oacute;pez (2001-2003): he
@@ -118,6 +121,64 @@ capabilities are built. Toon Knapen helped adjust the library for VisualAge 6.0.
Markus Sch&ouml;pflin provided a Jamfile tweak for GCC under Tru64 UNIX.
</p>
<h2><a name="boost_1_34">Boost 1.34 release</a></h2>
<p>
<span style="float:left;margin-right:10px"><img src="hector.jpg" width="150" height="198"></span>
Thanks go to Pavel Vo&#382;en&iacute;lek for his useful comments and suggestions
during the development of this release, and to Rosa Bern&aacute;rdez for reviewing
the new material in the documentation.
Alo Sarv suggested a notational improvement in the specification of
partial searches with composite keys.
Maxim Yegorushkin proposed a valuable
<a href="tutorial/indices.html#ordered_node_compression">spatial optimization</a>
for ordered indices and provided figures of its impact on performance
for containers with large numbers of elements.
Caleb Epstein performed the tests under MSVC++ 8.0 described in the
performance section. The following people have reported bugs and problems with
previous versions and prereleases of the library: Alexei Alexandrov,
Mat&iacute;as Capeletto, John Eddy, Martin Eigel, Guillaume Lazzara,
Felipe Magno de Almeida, Julien Pervill&eacute;, Hubert Schmid, Toby Smith.
</p>
<p>
New member in the family! Thanks to H&eacute;ctor for his patience during
long development sessions and his occasional contributions to the source
codebase.
<br style="clear:all;">
</p>
<h2><a name="boost_1_35">Boost 1.35 release</a></h2>
<p>
<a href="tutorial/key_extraction.html#global_fun"><code>global_fun</code></a>
was included after a proposal by Markus Werle. Bruno Mart&iacute;nez Aguerre
suggested the inclusion of
<a href="tutorial/indices.html#iterator_to"><code>iterator_to</code></a>. The
rollback versions of <code>modify</code> and <code>modify_key</code> arose
from discussions with Mat&iacute;as Capeletto. Steven Watanabe spotted an
include guard bug present from the first release of the library.
</p>
<h2><a name="boost_1_36">Boost 1.36 release</a></h2>
<p>
Thanks to Amit Jain for reporting a problem with allocator management.
Michael Fawcett proposed the addition of an allocator constructor to
<code>multi_index_container</code>.
A report from Zachary Zhou has led to
<a href="release_notes.html#stable_update">enhancing the behavior of
hashed indices update functions</a> so that they meet some intuitive expectations.
Grzegorz Jakacki spotted some internal dead code.
</p>
<h2><a name="boost_1_56">Boost 1.56 release</a></h2>
<p>
Stephen Kelly has contributed the removal of workaround code for old compilers
no longer supported.
</p>
<hr>
<div class="prev_link"><a href="release_notes.html"><img src="prev.gif" alt="release notes" border="0"><br>
@@ -131,9 +192,9 @@ Index
<br>
<p>Revised July 11th 2005</p>
<p>Revised October 9th 2013</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
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">
File diff suppressed because it is too large Load Diff
-941
View File
@@ -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>&lt;...&gt;</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>&lt;...&gt;</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>&lt;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>&lt;...&gt;</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>&lt;...&gt;</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>&lt;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>&lt;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>&lt;...&gt;</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>&lt;...&gt;</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>&lt;</span><span class=identifier>iostream</span><span class=special>&gt;</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>&lt;</span><span class=keyword>int</span> <span class=identifier>pair</span><span class=special>::*</span> <span class=identifier>PtrToPairMember</span><span class=special>&gt;</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>&amp;</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>&lt;&amp;</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>x</span><span class=special>&gt;</span> <span class=identifier>fx</span><span class=special>;</span>
<span class=identifier>foo</span><span class=special>&lt;&amp;</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>y</span><span class=special>&gt;</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>&lt;&lt;</span><span class=string>&quot;KO&quot;</span><span class=special>&lt;&lt;</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>&lt;&lt;</span><span class=string>&quot;OK&quot;</span><span class=special>&lt;&lt;</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&lt;A,int,&amp;A::x></code> can be simulated then
as <code>member_offset&lt;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>&lt;</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>x</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
or alternatively to
</p>
<blockquote><pre>
<span class=identifier>member_offset</span><span class=special>&lt;</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>)&gt;</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&lt;A,int,&amp;A::f></code> can be replaced by
<code>const_mem_fun_explicit&lt;A,int,int (A::*)()const,&amp;A::f></code>. 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>&lt;</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
but resolves to
</p>
<blockquote><pre>
<span class=identifier>const_mem_fun_explicit</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>&gt;</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>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
<span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>family_name</span><span class=special>&gt;,</span>
<span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>given_name</span><span class=special>&gt;</span>
<span class=special>&gt;</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>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=identifier>ckey_t</span><span class=special>,</span>
<span class=comment>// composite_key_result_less plays the role of
// std::less&lt;ckey_t::result_type&gt;</span>
<span class=identifier>composite_key_result_less</span><span class=special>&lt;</span><span class=identifier>ckey_t</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>&gt;</span>
<span class=special>&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span>
<span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>phone_number</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</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">&nbsp;<code>indexed_by</code>&nbsp;</td>
<td align="center">&nbsp;<code>BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE</code>&nbsp;</td>
<td align="center">20</td>
<td align="center">5</td>
</tr>
<tr class="odd_tr">
<td align="center">&nbsp;<code>tag</code>&nbsp;</td>
<td align="center">&nbsp;<code>BOOST_MULTI_INDEX_LIMIT_TAG_SIZE</code>&nbsp;</td>
<td align="center">20</td>
<td align="center">3</td>
</tr>
<tr>
<td align="center">&nbsp;<code>composite_key</code>&nbsp;</td>
<td align="center">&nbsp;<code>BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE</code>&nbsp;</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>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
<p>
Then, for instance, the type <code>employee_set::nth_type&lt;0&gt;::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>&lt;</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</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>&lt;</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>&lt;</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_unique</span><span class=special>&lt;</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</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>&gt;,</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>&lt;</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special>&lt;</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>&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;,</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>&gt;,</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>&lt;</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span> <span class=keyword>int</span><span class=special>,</span> <span class=special>&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>&gt;,</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>&gt;,</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>&gt;,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span>
<span class=special>&gt;,</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>&lt;</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>&gt;,</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>&gt;</span>
</pre></blockquote>
<p>
It can be seen that a significant portion of the type name is contributed by
the <code>indexed_by&lt;...&gt;</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>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>{};</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>employee_set_indices</span>
<span class=special>&gt;</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&lt;0&gt;::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>&lt;</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</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>&lt;</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>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span>
<span class=special>&gt;,</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>&lt;</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>&gt;,</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>&gt;</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&lt;...&gt;</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>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>
+125 -22
View File
@@ -5,6 +5,10 @@
<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">
<link rel="start" href="index.html">
<link rel="prev" href="performance.html">
<link rel="up" href="index.html">
<link rel="next" href="tests.html">
</head>
<body>
@@ -27,7 +31,7 @@ Tests
<ul>
<li><a href="#example1">Example 1: basic usage</a></li>
<li><a href="#example2">Example 2: using member functions as keys</a></li>
<li><a href="#example2">Example 2: using functions as keys</a></li>
<li><a href="#example3">Example 3: constructing <code>multi_index_container</code>s
with <code>ctor_args_list</code></a></li>
<li><a href="#example4">Example 4: bidirectional map</a></li>
@@ -36,6 +40,9 @@ Tests
<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>
<li><a href="#example10">Example 10: random access indices</a></li>
<li><a href="#example11">Example 11: index rearrangement</a></li>
<li><a href="#example12">Example 12: using Boost.Interprocess allocators</a></li>
</ul>
<h2><a name="example1">Example 1: basic usage</a></h2>
@@ -49,23 +56,23 @@ Basic program showing the multi-indexing capabilities of Boost.MultiIndex
with an admittedly boring set of <code>employee</code> records.
</p>
<h2><a name="example2">Example 2: using member functions as keys</a></h2>
<h2><a name="example2">Example 2: using functions as keys</a></h2>
<p>
See <a href="../example/memfun_key.cpp">source code</a>.
See <a href="../example/fun_key.cpp">source code</a>.
</p>
<p>
Usually keys assigned to an index are based on a member variable of the
element, but key extractors can be defined which take their value from
a member function. This has some similarity with the concept of
a member function or a global function. This has some similarity with the concept of
<i>calculated keys</i> supported by some relational database engines.
The example shows how to use the predefined <code>const_mem_fun</code>
key extractor to deal with this situation.
and <code>global_fun</code> key extractors to deal with this situation.
</p>
<p>
Keys based on member functions usually will not be actual references,
Keys based on functions usually will not be actual references,
but rather the temporary values resulting from the invocation of the
member function used. This implies that <code>modify_key</code> cannot be
applied to this type of extractors, which is a perfectly logical
@@ -82,7 +89,7 @@ See <a href="../example/non_default_ctor.cpp">source code</a>.
<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
<a href="tutorial/creation.html#ctor_args_list">tutorial</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>.
@@ -97,14 +104,20 @@ See <a href="../example/bimap.cpp">source code</a>.
<p>
This example shows how to construct a bidirectional map with
<code>multi_index_container</code>. By a <i>bidirectional map</i> we mean
a container of elements of <code>std::pair&lt;const FromType,const ToType></code>
such that no two elements exists with the same <code>first</code>
<i>or</i> <code>second</code> value (<code>std::map</code> only
guarantees uniqueness of the first member). Fast lookup is provided
a container of <code>(const FromType,const ToType)</code> pairs
such that no two elements exist with the same first
<i>or</i> second component (<code>std::map</code> only
guarantees uniqueness of the first component). Fast lookup is provided
for both keys. The program features a tiny Spanish-English
dictionary with online query of words in both languages.
</p>
<p>
This bidirectional map can be considered as a primitive precursor
to the full-fledged container provided by
<a href="../../bimap/index.html">Boost.Bimap</a>.
</p>
<h2><a name="example5">Example 5: sequenced indices</a></h2>
<p>
@@ -136,7 +149,7 @@ be defined as:
<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=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>
@@ -161,17 +174,17 @@ involves having the manufactures stored in a separate
<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=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>model</span><span class=special>;</span>
<span class=keyword>const</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
<a href="tutorial/key_extraction.html#advanced_key_extractors">advanced features
of Boost.MultiIndex key extractors</a> in the tutorial), this case
is complex enough that a suitable key extractor has to be defined. The following
utility cascades two key extractors:
</p>
@@ -209,7 +222,7 @@ of its associated <code>car_manufacturer</code> can be accomplished with
<blockquote><pre>
<span class=identifier>key_from_key</span><span class=special>&lt;</span>
<span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>car_manufacturer</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;,</span>
<span class=identifier>member</span><span class=special>&lt;</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>&gt;</span>
<span class=identifier>member</span><span class=special>&lt;</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>*,&amp;</span><span class=identifier>car_model</span><span class=special>::</span><span class=identifier>manufacturer</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
</pre></blockquote>
@@ -251,7 +264,7 @@ See <a href="../example/composite_keys.cpp">source code</a>.
</p>
<p>
Boost.MultiIndex <a href="advanced_topics.html#composite_keys">
Boost.MultiIndex <a href="tutorial/key_extraction.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
@@ -294,7 +307,7 @@ 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>
<li>Use <a href="tutorial/creation.html#serialization">serialization</a>
to store and retrieve the filesystem state between program runs.</li>
</ul>
</p>
@@ -333,6 +346,96 @@ 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>
<h2><a name="example10">Example 10: random access indices</a></h2>
<p>
See <a href="../example/random_access.cpp">source code</a>.
</p>
<p>
The example resumes the text container introduced in
<a href="#example5">example 5</a> and shows how substituting a random
access index for a sequenced index allows for extra capabilities like
efficient access by position and calculation of the offset of a given
element into the container.
</p>
<h2><a name="example11">Example 11: index rearrangement</a></h2>
<p>
See <a href="../example/rearrange.cpp">source code</a>.
</p>
<p>
There is a relatively common piece of urban lore claiming that
a deck of cards must be shuffled seven times in a row to be perfectly
mixed. The statement derives from the works of mathematician Persi
Diaconis on <i>riffle shuffling</i>: this shuffling
technique involves splitting the deck in two packets roughly the same
size and then dropping the cards from both packets so that they become
interleaved. It has been shown that when repeating this procedure
seven times the statistical distribution of cards is reasonably
close to that associated with a truly random permutation. A measure
of "randomness" can be estimated by counting <i>rising sequences</i>:
consider a permutation of the sequence 1,2, ... , <i>n</i>, a rising sequence
is a maximal chain of consecutive elements <i>m</i>, <i>m+1</i>, ... , <i>m+r</i>
such that they are arranged in ascending order. For instance, the permutation
125364789 is composed of the two rising sequences 1234 and 56789,
as becomes obvious by displaying the sequence like this,
<span style="vertical-align:sub">1</span><span style="vertical-align:sub">2</span><span style="vertical-align:super">5</span><span style="vertical-align:sub">3</span><span style="vertical-align:super">6</span><span style="vertical-align:sub">4</span><span style="vertical-align:super">7</span><span style="vertical-align:super">8</span><span style="vertical-align:super">9</span>.
The average number of rising sequences in a random permutation of
<i>n</i> elements is (<i>n</i>+1)/2: by contrast, after a single riffle
shuffle of an initially sorted deck of cards, there cannot be more than
two rising sequences. The average number of rising sequences approximates
to (<i>n</i>+1)/2 as the number of consecutive riffle shuffles increases,
with seven shuffles yielding a close result for a 52-card poker deck.
Brad Mann's paper
<a href="http://www.dartmouth.edu/~chance/teaching_aids/books_articles/Mann.pdf">"How
many times should you shuffle a deck of cards?"</a> provides a
rigorous yet very accessible treatment of this subject.
</p>
<p>
The example program estimates the average number of rising sequences
in a 52-card deck after repeated riffle shuffling as well as applying
a completely random permutation. The deck is modeled by the following
container:
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>random_access</span><span class=special>&lt;&gt;,</span>
<span class=identifier>random_access</span><span class=special>&lt;&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span>
</pre></blockquote>
where the first index stores the current arrangement of the deck, while
the second index is used to remember the start position. This representation
allows for an efficient implementation of a rising sequences counting
algorithm in linear time.
<a href="reference/rnd_indices.html#rearrange"><code>rearrange</code></a>
is used to apply to the deck a shuffle performed externally on an
auxiliary data structure.
</p>
<h2><a name="example12">Example 12: using Boost.Interprocess allocators</a></h2>
<p>
See <a href="../example/ip_allocator.cpp">source code</a>.
</p>
<p>
Boost.MultiIndex supports special allocators such as those provided by
<a href="../../interprocess/index.html">Boost.Interprocess</a>,
which allows for <code>multi_index_container</code>s to be placed in shared
memory. The example features a front-end to a small book database
implemented by means of a <code>multi_index_container</code> stored
in a Boost.Interprocess memory mapped file. The reader can verify that several
instances of the program correctly work simultaneously and immediately see
the changes to the database performed by any other instance.
</p>
<hr>
<div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br>
@@ -347,9 +450,9 @@ Tests
<br>
<p>Revised March 8th 2005</p>
<p>Revised November 18th 2019</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2019 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+6 -75
View File
@@ -5,6 +5,10 @@
<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">
<link rel="start" href="index.html">
<link rel="prev" href="tests.html">
<link rel="up" href="index.html">
<link rel="next" href="release_notes.html">
</head>
<body>
@@ -33,47 +37,12 @@ principle driving the current internal design of <code>multi_index_container</co
<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>
@@ -165,19 +134,6 @@ simple enough to make them worth documenting so that the (bold)
user can write implementations for her own indices.
</p>
<h2><a name="bimap">Bidirectional map</a></h2>
<p>
<a href="examples.html#example4">Example 4</a> in the examples section
features a <i>bidirectional map</i>, implemented as a
<code>multi_index_container</code> with two unique ordered indices. This particular
structure is deemed important enough as to provide it as a separate
class template, relying internally in <code>multi_index_container</code>. As
feedback is collected from the users of Boost.MultiIndex, other singular
instantiations of <code>multi_index_container</code> might be encapsulated
to form a component library of ready to use containers.
</p>
<h2><a name="indexed_maps">Indexed maps</a></h2>
<p>
@@ -216,31 +172,6 @@ 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&lt;Programming>: Move Constructors"</a>.) Move semantics
alleviates the computational load involved in the creation and copying
of temporary objects, specially for heavy classes as
<code>multi_index_container</code>s are. David Abrahams and Gary Powell provide
an alternative implementation of move semantics in their paper
<a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html">
"Clarification of Initialization of Class Objects by rvalues"</a> for
the C++ Evolution Working Group.
</p>
<p>
Adding move semantics to <code>multi_index_container</code> is particularly
beneficial when the container is used as an internal building block in other
libraries (vg. relational database frameworks), enabling the efficient
development of functions returning <code>multi_index_container</code>s. Without support
for move semantics, this scheme is impractical and less elegant syntaxes
should be resorted to.
</p>
<hr>
<div class="prev_link"><a href="tests.html"><img src="prev.gif" alt="tests" border="0"><br>
@@ -255,9 +186,9 @@ Release notes
<br>
<p>Revised July 5th 2005</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

+17 -16
View File
@@ -5,15 +5,17 @@
<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">
<link rel="start" href="index.html">
<link rel="next" href="tutorial/index.html">
</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>
<div class="prev_link">&nbsp;</div>
<div class="up_link">&nbsp;</div>
<div class="next_link"><a href="tutorial/index.html"><img src="next.gif" alt="tutorial" border="0"><br>
Tutorial
</a></div><br clear="all" style="clear: all;">
@@ -29,12 +31,13 @@ borrowed from relational database terminology and allows for the specification o
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.
<code>std::list</code> and <code>std::unordered_set</code>.
</p>
<p>
Boost.MultiIndex features additional functionalities, like subobject searching,
range querying and in-place updating of elements, which make it a convenient replacement
range querying, in-place updating of elements and calculation of ranks,
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>
@@ -44,16 +47,16 @@ 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
<li><a href="tutorial/basics.html#multiple_sort">Sets with several iteration orders
and search criteria</a>.</li>
<li><a href="tutorial.html#list_fast_lookup">Lists with fast lookup</a>
<li><a href="tutorial/basics.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
<li><a href="tutorial/techniques.html#emulate_std_containers">Emulations of
standard containers</a> taking advantage of the extra functionalities
provided by Boost.MultiIndex.</li>
</ul>
@@ -62,10 +65,8 @@ examples of use developed in the documentation:
<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="tutorial/index.html">Tutorial</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>
@@ -76,17 +77,17 @@ examples of use developed in the documentation:
<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>
<div class="prev_link">&nbsp;</div>
<div class="up_link">&nbsp;</div>
<div class="next_link"><a href="tutorial/index.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>Revised November 7th 2025</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2025 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 10 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

+137 -99
View File
@@ -5,14 +5,18 @@
<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">
<link rel="start" href="index.html">
<link rel="prev" href="reference/key_extraction.html">
<link rel="up" href="index.html">
<link rel="next" href="examples.html">
</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
<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
@@ -91,7 +95,7 @@ STL containers.
<h2><a name="simulation">Manual simulation of a <code>multi_index_container</code></a></h2>
<p>
The section of <a href="advanced_topics.html#simulate_std_containers">simulation
The section on <a href="tutorial/techniques.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
@@ -107,7 +111,7 @@ Consider the following instantiation of <code>multi_index_container</code>:
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>indexed_t</span><span class=special>;</span>
</pre></blockquote>
@@ -154,8 +158,8 @@ inefficient, though: while insertion into the data structure is simple enough:
<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>(&amp;*</span><span class=identifier>t1</span><span class=special>);</span>
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it1</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>(&amp;*</span><span class=identifier>it1</span><span class=special>);</span>
</pre></blockquote>
deletion, on the other hand, necessitates a logarithmic search, whereas
@@ -164,8 +168,8 @@ deletion, on the other hand, necessitates a logarithmic search, whereas
<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>
<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>it2</span><span class=special>);</span>
</pre></blockquote>
<p>
@@ -174,14 +178,14 @@ 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>&lt;</span><span class=keyword>int</span><span class=special>&gt;</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>set</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</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>&lt;</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>&lt;</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>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>manual_t2</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #1</span>
<span class=special>&gt;</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>
@@ -194,17 +198,17 @@ equivalent to those of <code>indexed_t</code>:
<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=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it1</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>it1</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>
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>it2</span><span class=special>);</span>
</pre></blockquote>
<p>
The construction can be extended in a straightworward manner to
The construction can be extended in a straightforward 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.
@@ -216,7 +220,7 @@ manual simulations.
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>.)
issues (which in general play in favor of <code>multi_index_container</code>).
</p>
<p>
@@ -226,7 +230,7 @@ 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>S<sub>I</sub></i> = <i>e</i> + <i>h</i><sub>0</sub> + &middot;&middot;&middot; +
<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.
@@ -237,13 +241,13 @@ 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,
is independent of the type of the elements. Summing 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>1</sub>) + &middot;&middot;&middot; +
(<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>
@@ -263,7 +267,25 @@ then as:
<p>
The formula shows that <code>multi_index_container</code> is more efficient
with regard to memory consumption as the number of indices grow.
with regard to memory consumption as the number of indices grow. An implicit
assumption has been made that headers of <code>multi_index_container</code>
index nodes are the same size that their analogues in STL containers; but there
is a particular case in which this is often not the case: ordered indices use a
<a href="tutorial/indices.html#ordered_node_compression">spatial optimization
technique</a> which is not present in many implementations of
<code>std::set</code>, giving an additional advantage to
<code>multi_index_container</code>s of one system word per ordered index.
Taking this fact into account, the former formula can be adjusted to:
</p>
<blockquote>
<i>S<sub>I</sub></i>&nbsp;/&nbsp;<i>S<sub>M</sub></i> =
<i>S<sub>I</sub></i>&nbsp;/&nbsp;(<i>S<sub>I</sub></i> + (<i>N</i>-1)<i>p</i> + <i>Ow</i>),
</blockquote>
<p>
where <i>O</i> is the number of ordered indices of the container, and <i>w</i>
is the system word size (typically 4 bytes on 32-bit architectures).
</p>
<p>
@@ -289,9 +311,9 @@ will see later, the reduction can be very significative for
</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.
resulting performance will roughly match that of the STL equivalent containers:
tests show that there is at most a negligible degradation with respect to STL,
and even in some cases a small improvement.
</p>
<h2><a name="tests">Performance tests</a></h2>
@@ -314,15 +336,33 @@ has been measured for different instantiations of <code>multi_index_container</c
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.
STL containers. The table below describes the test environments used.
</p>
<p align="center">
<table cellspacing="0" cellpadding="5">
<caption><b>Tests environments.</b></caption>
<tr>
<th>Compiler</th>
<th>Settings</th>
<th>OS and CPU</th>
</tr>
<tr>
<td>GCC 3.4.5 (mingw special)</td>
<td><code>-O3</code></td>
<td>Windows 2000 Pro on P4 1.5 GHz, 256 MB RAM</td>
</tr>
<tr class="odd_tr">
<td>Intel C++ 7.1</td>
<td>default release settings</td>
<td>Windows 2000 Pro on P4 1.5 GHz, 256 MB RAM</td>
</tr>
<tr>
<td>Microsoft Visual C++ 8.0</td>
<td>default release settings, <code>_SECURE_SCL=0</code></td>
<td>Windows XP on P4 Xeon 3.2 GHz, 1 GB RAM</td>
</tr>
</table>
</p>
<p>
@@ -357,14 +397,14 @@ which is functionally equivalent to <code>std::set&lt;int></code>.
<p align="center">
<table cellspacing="0">
<tr>
<th width="33%">GCC 3.1.1</th>
<th width="33%">GCC 3.4.5</th>
<th width="33%">ICC 7.1</th>
<th width="33%">MSVC 6.5</th>
<th width="33%">MSVC 8.0</th>
</tr>
<tr>
<td align="center">100%</td>
<td align="center">100%</td>
<td align="center">100%</td>
<td align="center">80%</td>
<td align="center">80%</td>
<td align="center">80%</td>
</tr>
</table>
<b>Table 1: Relative memory consumption of <code>multi_index_container</code> with 1
@@ -372,8 +412,8 @@ 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.
The reduction in memory usage is accounted for by the optimization technique implemented
in Boost.MultiIndex ordered indices, as <a href="#spatial_efficiency">explained above</a>.
</p>
<h4><a name="time_1r">Execution time</a></h4>
@@ -385,11 +425,12 @@ width="556" height="372"><br>
</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.
Somewhat surprisingly, <code>multi_index_container</code> performs slightly
better than <code>std::set</code>. A very likely explanation for this behavior
is that the lower memory consumption of <code>multi_index_container</code>
results in a higher processor cache hit rate.
The improvement is smallest for GCC, presumably because the worse quality of
this compiler's optimizer masks the cache-related benefits.
</p>
<h3><a name="test_1s">Results for 1 sequenced index</a></h3>
@@ -416,9 +457,9 @@ which is functionally equivalent to <code>std::list&lt;int></code>.
<p align="center">
<table cellspacing="0">
<tr>
<th width="33%">GCC 3.1.1</th>
<th width="33%">GCC 3.4.5</th>
<th width="33%">ICC 7.1</th>
<th width="33%">MSVC 6.5</th>
<th width="33%">MSVC 8.0</th>
</tr>
<tr>
<td align="center">100%</td>
@@ -432,7 +473,7 @@ sequenced index.</b>
<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.
same size as those of its <code>std::list</code> counterpart.
</p>
<h4><a name="time_1s">Execution time</a></h4>
@@ -444,9 +485,10 @@ width="556" height="372"><br>
</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%.
<code>multi_index_container</code> does not attain the performance
of its STL counterpart, although the figures are close. Again, the worst results
are those of GCC, with a degradation of up to 7%, while ICC and MSVC do not
exceed a mere 5%.
</p>
<h3><a name="test_2r">Results for 2 ordered indices</a></h3>
@@ -470,14 +512,14 @@ The following instantiation of <code>multi_index_container</code> was tested:
<p align="center">
<table cellspacing="0">
<tr>
<th width="33%">GCC 3.1.1</th>
<th width="33%">GCC 3.4.5</th>
<th width="33%">ICC 7.1</th>
<th width="33%">MSVC 6.5</th>
<th width="33%">MSVC 8.0</th>
</tr>
<tr>
<td align="center">90%</td>
<td align="center">90%</td>
<td align="center">90%</td>
<td align="center">70%</td>
<td align="center">70%</td>
<td align="center">70%</td>
</tr>
</table>
<b>Table 3: Relative memory consumption of <code>multi_index_container</code> with 2
@@ -485,8 +527,8 @@ 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.
These results coincide with the theoretical formula for
<i>S<sub>I</sub></i> = 28, <i>N</i> = <i>O</i> = 2 and <i>p</i> = <i>w</i> = 4.
</p>
<h4><a name="time_2r">Execution time</a></h4>
@@ -500,7 +542,9 @@ width="556" height="372"><br>
<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.
which in this case lies around 60%. There is no obvious explanation for the
increased advantage of <code>multi_index_container</code> in MSVC for
<i>n</i>=10<sup>5</sup>.
</p>
<h3><a name="test_1r1s">Results for 1 ordered index + 1 sequenced index</a></h3>
@@ -524,14 +568,14 @@ The following instantiation of <code>multi_index_container</code> was tested:
<p align="center">
<table cellspacing="0">
<tr>
<th width="33%">GCC 3.1.1</th>
<th width="33%">GCC 3.4.5</th>
<th width="33%">ICC 7.1</th>
<th width="33%">MSVC 6.5</th>
<th width="33%">MSVC 8.0</th>
</tr>
<tr>
<td align="center">87.5%</td>
<td align="center">87.5%</td>
<td align="center">87.5%</td>
<td align="center">75%</td>
<td align="center">75%</td>
<td align="center">75%</td>
</tr>
</table>
<b>Table 4: Relative memory consumption of <code>multi_index_container</code> with 1
@@ -539,8 +583,8 @@ 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.
These results coincide with the theoretical formula for
<i>S<sub>I</sub></i> = 24, <i>N</i> = 2, <i>O</i> = 1 and <i>p</i> = <i>w</i> = 4.
</p>
<h4><a name="time_1r1s">Execution time</a></h4>
@@ -556,17 +600,13 @@ width="556" height="372"><br>
<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.
improvement of 50-65% 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.)
<i>n</i>=10<sup>5</sup> for two of the compilers, namely GCC and ICC.
In order to rule out spurious results, the tests
have been run many times, yielding similar outcomes. Both test environments
are deployed on the same machine, which points to some OS-related reason for
this phenomenon.
</p>
<h3><a name="test_3r">Results for 3 ordered indices</a></h3>
@@ -591,14 +631,14 @@ The following instantiation of <code>multi_index_container</code> was tested:
<p align="center">
<table cellspacing="0">
<tr>
<th width="33%">GCC 3.1.1</th>
<th width="33%">GCC 3.4.5</th>
<th width="33%">ICC 7.1</th>
<th width="33%">MSVC 6.5</th>
<th width="33%">MSVC 8.0</th>
</tr>
<tr>
<td align="center">86.7%</td>
<td align="center">86.7%</td>
<td align="center">86.7%</td>
<td align="center">66.7%</td>
<td align="center">66.7%</td>
<td align="center">66.7%</td>
</tr>
</table>
<b>Table 5: Relative memory consumption of <code>multi_index_container</code> with 3
@@ -606,9 +646,8 @@ 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.
These results coincide with the theoretical formula for
<i>S<sub>I</sub></i> = 40, <i>N</i> = <i>O</i> = 3 and <i>p</i> = <i>w</i> = 4.
</p>
<h4><a name="time_3r">Execution time</a></h4>
@@ -620,7 +659,7 @@ width="556" height="372"><br>
</p>
<p>
Execution time for this case is between 55% and 65% lower than achieved with
Execution time for this case is between 45% and 55% lower than achieved with
an STL-based manual simulation of the same data structure.
</p>
@@ -646,14 +685,14 @@ The following instantiation of <code>multi_index_container</code> was tested:
<p align="center">
<table cellspacing="0">
<tr>
<th width="33%">GCC 3.1.1</th>
<th width="33%">GCC 3.4.5</th>
<th width="33%">ICC 7.1</th>
<th width="33%">MSVC 6.5</th>
<th width="33%">MSVC 8.0</th>
</tr>
<tr>
<td align="center">84.6%</td>
<td align="center">84.6%</td>
<td align="center">84.6%</td>
<td align="center">69.2%</td>
<td align="center">69.2%</td>
<td align="center">69.2%</td>
</tr>
</table>
<b>Table 6: Relative memory consumption of <code>multi_index_container</code> with 2
@@ -661,8 +700,8 @@ 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.
These results coincide with the theoretical formula for
<i>S<sub>I</sub></i> = 36, <i>N</i> = 3, <i>O</i> = 2 and <i>p</i> = <i>w</i> = 4.
</p>
<h4><a name="time_2r1s">Execution time</a></h4>
@@ -686,21 +725,20 @@ factor, which ranges from 45% to 55%.
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.
of indices increases.
</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.
<code>multi_index_container</code>s, the performance of Boost.MultiIndex
is comparable with that of the tested STL implementations, and can even yield
some improvements both in space consumption and execution time.
</p>
<hr>
<div class="prev_link"><a href="compiler_specifics.html"><img src="prev.gif" alt="compiler specifics" border="0"><br>
Compiler specifics
<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
@@ -711,9 +749,9 @@ Examples
<br>
<p>Revised May 18th 2005</p>
<p>Revised November 7th 2025</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2025 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
File diff suppressed because it is too large Load Diff
+29 -7
View File
@@ -5,14 +5,18 @@
<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">
<link rel="start" href="../index.html">
<link rel="prev" href="../tutorial/techniques.html">
<link rel="up" href="../index.html">
<link rel="next" href="multi_index_container.html">
</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
<div class="prev_link"><a href="../tutorial/techniques.html"><img src="../prev.gif" alt="techniques" border="0"><br>
Techniques
</a></div>
<div class="up_link"><a href="../index.html"><img src="../up.gif" alt="index" border="0"><br>
Index
@@ -30,8 +34,10 @@ Index
<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="rnk_indices.html">Ranked 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="rnd_indices.html">Random access indices</a></li>
<li><a href="key_extraction.html">Key Extraction</a></li>
</ul>
@@ -54,6 +60,13 @@ The following dependencies among headers of Boost.MultiIndex hold:
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
</ul>
</li>
<li><a href="rnk_indices.html#synopsis">
<code>"boost/multi_index/ranked_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>
@@ -68,6 +81,13 @@ The following dependencies among headers of Boost.MultiIndex hold:
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
</ul>
</li>
<li><a href="rnd_indices.html#synopsis">
<code>"boost/multi_index/random_access_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>
@@ -76,7 +96,9 @@ The following dependencies among headers of Boost.MultiIndex hold:
<li><a href="key_extraction.html#member_synopsis">
<code>"boost/multi_index/member.hpp"</code></a>,</li>
<li><a href="key_extraction.html#mem_fun_synopsis">
<code>"boost/multi_index/mem_fun.hpp"</code></a> and</li>
<code>"boost/multi_index/mem_fun.hpp"</code></a>,</li>
<li><a href="key_extraction.html#global_fun_synopsis">
<code>"boost/multi_index/global_fun.hpp"</code></a> and</li>
<li><a href="key_extraction.html#composite_key_synopsis">
<code>"boost/multi_index/composite_key.hpp"</code></a>.</li>
</ul>
@@ -101,8 +123,8 @@ object modules.
<hr>
<div class="prev_link"><a href="../advanced_topics.html"><img src="../prev.gif" alt="advanced topics" border="0"><br>
Advanced topics
<div class="prev_link"><a href="../tutorial/techniques.html"><img src="../prev.gif" alt="techniques" border="0"><br>
Techniques
</a></div>
<div class="up_link"><a href="../index.html"><img src="../up.gif" alt="index" border="0"><br>
Index
@@ -113,9 +135,9 @@ Index
<br>
<p>Revised May 30th 2005</p>
<p>Revised November 24th 2015</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+87 -40
View File
@@ -5,6 +5,10 @@
<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">
<link rel="start" href="../index.html">
<link rel="prev" href="multi_index_container.html">
<link rel="up" href="index.html">
<link rel="next" href="ord_indices.html">
</head>
<body>
@@ -48,6 +52,7 @@ Ordered indices
<li><a href="#other_indices">Other types</a></li>
</ul>
</li>
<li><a href="#views">Index views</a></li>
</ul>
<h2><a name="index_concepts">Index concepts</a></h2>
@@ -76,8 +81,8 @@ 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:
its invariant (like uniqueness of elements). This circumstance, rather
than being 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
@@ -98,14 +103,15 @@ six primitives:
</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.
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
for replacement and modification 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
impact the interfaces of ordered and hashed indices, as they are based upon
those of associative and unordered associative containers, respectively,
and these containers
also have non-mutable elements; but it may come as a surprise when dealing
with sequenced indices, which are designed upon the functionality provided
with sequenced and random access indices, which are designed upon the functionality provided
by <code>std::list</code>.
</p>
@@ -113,13 +119,11 @@ by <code>std::list</code>.
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>.)
and random access indices have <code>push_back</code> and <code>push_front</code>
operations). Boost.MultiIndex poses no particular conditions on
the interface of indices, although each index provided satisfies the C++ requirements for
standard containers to the maximum extent possible within the conceptual framework
of the library.
</p>
<h2><a name="complexity_signature">Complexity signature</a></h2>
@@ -152,16 +156,16 @@ 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>
<code>O(i<sub>0</sub>(n)+&middot;&middot;&middot;+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>
<li><code>C(n)=c<sub>0</sub>(n)+&middot;&middot;&middot;+c<sub>N-1</sub>(n)</code>,</li>
<li><code>I(n)=i<sub>0</sub>(n)+&middot;&middot;&middot;+i<sub>N-1</sub>(n)</code>,</li>
<li><code>H(n)=h<sub>0</sub>(n)+&middot;&middot;&middot;+h<sub>N-1</sub>(n)</code>,</li>
<li><code>D(n)=d<sub>0</sub>(n)+&middot;&middot;&middot;+d<sub>N-1</sub>(n)</code>,</li>
<li><code>R(n)=r<sub>0</sub>(n)+&middot;&middot;&middot;+r<sub>N-1</sub>(n)</code>,</li>
<li><code>M(n)=m<sub>0</sub>(n)+&middot;&middot;&middot;+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>
@@ -185,11 +189,16 @@ index specifiers
<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="rnk_indices.html#unique_non_unique"><code>ranked_unique</code> and
<code>ranked_non_unique</code></a> for
<a href="rnk_indices.html">ranked 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>
<li><a href="seq_indices.html#sequenced"><code>sequenced</code></a> for
<a href="seq_indices.html">sequenced indices</a>,</li>
<li>and <a href="rnd_indices.html#random_access"><code>random_access</code></a> for
<a href="rnd_indices.html">random access indices</a>.</li>
</ul>
</p>
@@ -203,7 +212,7 @@ index specifiers
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>T</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Ts</span><span class=special>&gt;</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>
@@ -214,24 +223,19 @@ index specifiers
<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
<code>indexed_by</code> is 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>&lt;</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>T</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Ts</span><span class=special>&gt;</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.
specifier. At least an element must be provided.
</p>
<h2><a name="tags">Tags</a></h2>
@@ -255,7 +259,7 @@ class template <a href="#tag"><code>tag</code></a>.
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Ts</span><span class=special>&gt;</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>
@@ -271,15 +275,13 @@ sequence of tags to be assigned to an index in instantiation time.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Ts</span><span class=special>&gt;</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>
@@ -293,7 +295,11 @@ 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>
on the key and provide fast lookup capabilities.</li>
<li><a href="rnk_indices.html">Ranked indices</a> are a variation of
ordered indices providing extra operations based on
<i>rank</i>, the numerical position of an element
in the sequence.</li>
<li><a href="hash_indices.html">Hashed indices</a> offer high
efficiency access through hashing techniques.</li>
</ul>
@@ -304,7 +310,48 @@ reference</a>.
<p>
<ul>
<li><a href="seq_indices.html">Sequenced indices</a> allow to arrange
elements as in a bidirectional list. </li>
elements as in a bidirectional list.</li>
<li><a href="rnd_indices.html">Random access indices</a> provide
constant time positional access and free ordering of elements.</li>
</ul>
</p>
<h2><a name="views">Index views</a></h2>
<p>
The following concept is used by the rearrange facilities of non-key-based
indices. Given an index <code>i</code> of type <code>Index</code>, a <i>view
of <code>i</code></i> is any range [<code>first</code>,<code>last</code>)
where <code>first</code> and <code>last</code> are input iterators such that
<ol>
<li>the associated value type of <code>Iterator</code> is convertible
to <code>const Index::value_type&amp;</code>
</li>
<li>and each of the elements of <code>i</code> appears exactly once in
[<code>first</code>,<code>last</code>).
</li>
</ol>
Note that the view refers to the actual elements of <code>i</code>, not to
copies of them. Additionally, a view is said to be <i>free</i> if its traversal
order is not affected by changes in the traversal order of <code>i</code>.
Examples of free views are:
<ul>
<li>[<code>c.begin()</code>,<code>c.end()</code>), where <code>c</code> is
any container of reference wrappers (from
<a href="../../../../doc/html/ref.html">Boost.Ref</a>) to the elements
of <code>i</code> containing exactly one reference to every element.
</li>
<li>[<code>i'.begin()</code>,<code>i'.end()</code>), where <code>i'</code> is
any index belonging to the same <code>multi_index_container</code>
as <code>i</code>, except <code>i</code> itself.
</li>
<li>
Any range which is a permutation of the ones described above, as for
instance [<code>c.rbegin()</code>,<code>c.rend()</code>), or
ranges obtained from the former with the aid of
<a href="../../../../libs/iterator/doc/permutation_iterator.html">
<code>permutation_iterator</code></a> from Boost.Iterator.
</li>
</ul>
</p>
@@ -322,9 +369,9 @@ Ordered indices
<br>
<p>Revised May 30th 2005</p>
<p>Revised October 25th 2025</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2025 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
File diff suppressed because it is too large Load Diff
+342 -148
View File
@@ -5,6 +5,10 @@
<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">
<link rel="start" href="../index.html">
<link rel="prev" href="index.html">
<link rel="up" href="index.html">
<link rel="next" href="indices.html">
</head>
<body>
@@ -84,6 +88,8 @@ synopsis</a>
</h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@@ -95,10 +101,15 @@ synopsis</a>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>nth_index</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=comment>// multi_index_container global functions for index retrieval:</span>
@@ -108,7 +119,7 @@ synopsis</a>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span>
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>);</span>
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>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>
@@ -116,7 +127,7 @@ synopsis</a>
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>);</span>
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>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>
@@ -124,7 +135,7 @@ synopsis</a>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span>
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>);</span>
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>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>
@@ -132,7 +143,7 @@ synopsis</a>
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>);</span>
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// multi_index_container global functions for projection of iterators:</span>
@@ -140,9 +151,9 @@ synopsis</a>
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
<span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
<span class=identifier>project</span><span class=special>(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>,</span>
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
@@ -151,9 +162,9 @@ synopsis</a>
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
<span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
<span class=identifier>project</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>,</span>
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
@@ -162,9 +173,9 @@ synopsis</a>
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
<span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
<span class=identifier>project</span><span class=special>(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>,</span>
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
@@ -173,9 +184,9 @@ synopsis</a>
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
<span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
<span class=identifier>project</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>,</span>
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
@@ -224,16 +235,15 @@ and for access to the indices held.
<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.
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</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>.)
<code>swap</code>).
</p>
<blockquote><pre>
@@ -253,6 +263,7 @@ operators and functions associated with the index (vg. comparison and
<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=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>node_type</span><span class=special>;</span>
<span class=comment>// nested class templates:</span>
@@ -260,52 +271,75 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>struct</span> <span class=identifier>nth_index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
<span class=comment>// construct/copy/destroy:</span>
<span class=identifier>multi_index_container</span><span class=special>();</span>
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(
</span><span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
</span><span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>,
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>);</span>
<span class=special>~</span><span class=identifier>multi_index_container</span><span class=special>();</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>)</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// retrieval of indices</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span> <span class=identifier>get</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span> <span class=identifier>get</span><span class=special>()</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</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>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// projection of iterators</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
<span class=comment>// multi_index_container associated global class templates:</span>
@@ -320,22 +354,26 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>nth_index_const_iterator</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index_iterator</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index_const_iterator</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
@@ -348,9 +386,9 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span>
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span>
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</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>&lt;</span><span class=identifier>N</span><span class=special>&gt;();</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>get</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;();</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
@@ -359,9 +397,9 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span>
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</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>&lt;</span><span class=identifier>N</span><span class=special>&gt;();</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>get</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;();</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
@@ -370,9 +408,9 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</span>
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span>
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;();</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>get</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;();</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
@@ -381,9 +419,9 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&amp;</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span>
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;();</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>get</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;();</span>
<span class=special>}</span>
<span class=comment>// multi_index_container global functions for projection of iterators:</span>
@@ -392,56 +430,56 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
<span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
<span class=identifier>project</span><span class=special>(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>,</span>
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
<span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
<span class=identifier>project</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>,</span>
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
<span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
<span class=identifier>project</span><span class=special>(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>,</span>
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
<span class=special>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
<span class=identifier>project</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>m</span><span class=special>,</span>
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=special>}</span>
<span class=comment>// comparison:</span>
@@ -487,26 +525,48 @@ scheme outlined in the
<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>Value</code> is the type of the elements contained. <code>Value</code> must be
<code>Erasable</code> from <code>multi_index_container</code>.
</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="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</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>.
construct can be used.
</li>
<li><code>Allocator</code> must be an allocator of <code>Value</code> objects
satisfying the associated C++ requirements at <b>[allocator.requirements]</b>.
The following relaxations to the standard requirements are allowed:
<ul>
<li>Non-equal allocator instances are supported: swapping two non-equal
instances must not throw any exception.
</li>
<li>For every type <code>T</code>,
the type <code>Allocator::rebind&lt;T&gt;::other::pointer</code> can be any
kind of random access iterator, provided that it is explicitly constructible from
the literal <code>0</code> (standing here as the null pointer) or from any
<code>p</code> of type <code>T*</code> pointing into an area allocated by
some instance of <code>Allocator</code> or some other allocator type rebound
from <code>Allocator</code>. A <code>pointer</code> constructed from
<code>p</code> shall dereference to <code>*p</code>.
</li>
</ul>
<code>multi_index_container</code>s and all their iterators do not store references
to allocated elements other than through the allocator's pointer type.
</li>
</ol>
Indices of a given <code>multi_index_container</code> instantiation cannot have
duplicate <a href="indices.html#tags">tags</a>, either within a single
index or in two different indices.
</p>
<p>
In what follows, the number of indices of the <code>multi_index_container</code>
is named <code>I</code>.
</p>
<h4><a name="types">Nested types</a></h4>
<code>ctor_args_list</code>
@@ -524,9 +584,8 @@ implicit conversion from
to <code>const ctor_args_list&amp;</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.
<code>DefaultConstructible</code>, provided that all <code>ctor_args</code> types
involved are <code>DefaultConstructible</code>.
</blockquote>
<code>index_specifier_type_list</code>
@@ -538,22 +597,16 @@ Same type as <code>IndexSpecifierList</code>.
<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
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</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
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</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>
@@ -561,15 +614,28 @@ specified.
<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
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</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>
<a name="node_type"><code>node_type</code></a>
<blockquote>
Node handle class following the standard specification at
<b>[container.node]</b> (version for set containers).
Two instantiations of <code>multi_index_container</code>
have compatible nodes (i.e., the same <code>node_type</code>) if and only if
they are of the form
<code>multi_index_container&lt;Value,IndexSpecifierList1,Allocator&gt;</code> and
<code>multi_index_container&lt;Value,IndexSpecifierList2,Allocator&gt;</code>,
have the same number <code>I</code> of index specifiers, and, for <code>i</code> =
<code>0</code>, ... , <code>I-1</code>, the respective <code>i</code>-th index specifiers
refer to the same <a href="indices.html#index_catalog">type of index</a>, regardless
of unique/non-unique variants and particular configuration type arguments.
</blockquote>
<h4><a name="nested_templates">Nested class templates</a></h4>
<code>template&lt;int N> struct nth_index</code>
@@ -578,14 +644,14 @@ as they were specified.
<code>nth_index&lt;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 &lt;= N &lt; I</code>.
<b>Requires:</b> <code>0 &lt;= N &lt; I-1</code>.
</blockquote>
<code>template&lt;typename Tag> struct index</code>
<blockquote>
<code>index&lt;Tag>::type</code> yields the type of the index which
has <code>Tag</code> as an associated <a href="indices.html#tags">tag type</a>.</br>
has <code>Tag</code> as an associated <a href="indices.html#tags">tag type</a>.<br>
<b>Requires:</b> Some index of the <code>multi_index_container</code> has <code>Tag</code>
as an associated tag type.
</blockquote>
@@ -595,6 +661,7 @@ as an associated tag type.
<blockquote>
<code>nth_index_iterator&lt;N>::type</code> is equivalent to
<code>nth_index&lt;N>::type::iterator</code>.<br>
<b>Note:</b> The use of <code>nth_index_iterator</code> is deprecated.
</blockquote>
<code>template&lt;int N> struct nth_index_const_iterator</code>
@@ -602,6 +669,7 @@ as an associated tag type.
<blockquote>
<code>nth_index_const_iterator&lt;N>::type</code> is equivalent to
<code>nth_index&lt;N>::type::const_iterator</code>.<br>
<b>Note:</b> The use of <code>nth_index_const_iterator</code> is deprecated.
</blockquote>
<code>template&lt;typename Tag> struct index_iterator</code>
@@ -609,6 +677,7 @@ as an associated tag type.
<blockquote>
<code>index_iterator&lt;Tag>::type</code> is equivalent to
<code>index&lt;Tag>::type::iterator</code>.<br>
<b>Note:</b> The use of <code>index_iterator</code> is deprecated.
</blockquote>
<code>template&lt;typename Tag> struct index_const_iterator</code>
@@ -616,12 +685,21 @@ as an associated tag type.
<blockquote>
<code>index_const_iterator&lt;Tag>::type</code> is equivalent to
<code>index&lt;Tag>::type::const_iterator</code>.<br>
<b>Note:</b> The use of <code>index_const_iterator</code> is deprecated.
</blockquote>
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
<code>multi_index_container();</code>
<blockquote>
<b>Effects:</b> Constructs an empty <code>multi_index_container</code> using the
default values of <code>ctor_args_list</code> and <code>allocator_type</code>.<br>
<b>Complexity:</b> Constant.
</blockquote>
<code>explicit multi_index_container(<br>
&nbsp;&nbsp;const ctor_args_list&amp; comp=ctor_args_list(),<br>
&nbsp;&nbsp;const ctor_args_list&amp; args_list,<br>
&nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code>
<blockquote>
@@ -630,19 +708,27 @@ specified argument list and allocator.<br>
<b>Complexity:</b> Constant.
</blockquote>
<code>explicit multi_index_container(const allocator_type&amp; al);</code>
<blockquote>
<b>Effects:</b> Constructs an empty <code>multi_index_container</code> using the
specified allocator and the default value of <code>ctor_args_list</code>.<br>
<b>Complexity:</b> Constant.
</blockquote>
<code>template&lt;typename InputIterator><br>
multi_index_container(<br>
&nbsp;&nbsp;InputIterator first,InputIterator last,<br>
&nbsp;&nbsp;const ctor_args_list&amp; comp=ctor_args_list(),<br>
&nbsp;&nbsp;const ctor_args_list&amp; args_list=ctor_args_list(),<br>
&nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code>
<blockquote>
<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
<b>Requires:</b> <code>InputIterator</code> is an input iterator.
<code>Value</code> is
<code>EmplaceConstructible</code> into <code>multi_index_container</code>
from <code>*first</code>.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> Constructs an 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
@@ -651,19 +737,80 @@ on the acceptance by all the indices of the <code>multi_index_container</code>.<
the number of elements in [<code>first</code>,<code>last</code>).<br>
</blockquote>
<code>multi_index_container(<br>
&nbsp;&nbsp;std::initializer_list&lt;Value&gt; list,<br>
&nbsp;&nbsp;const ctor_args_list&amp; args_list=ctor_args_list(),<br>
&nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code>
<blockquote>
<b>Effects:</b> Equivalent to
<code>multi_index_container(list.begin(),list.end(),args_list,al)</code>.
</blockquote>
<code>multi_index_container(<br>
&nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Constructs a copy of <code>x</code>, copying its
elements as well as its internal objects (key extractors, comparison objects,
allocator.)<br>
elements as well as its internal objects (those specified
in <code>ctor_args_list</code> and the 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(<br>
&nbsp;&nbsp;multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b> Constructs a <code>multi_index_container</code> by transferring the
elements of <code>x</code> and copying its internal objects (those specified
in <code>ctor_args_list</code> and the allocator).<br>
<b>Postconditions:</b> If <code>x==y</code> just
before the movement, <code>*this==y</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
<b>Complexity:</b> Constant.
</blockquote>
<code>multi_index_container(<br>
&nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x,<br>
&nbsp;&nbsp;const allocator_type&amp; al);</code>
<blockquote>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Constructs a copy of <code>x</code>, copying its
elements and its internal objects (those specified
in <code>ctor_args_list</code>) and using a copy of the allocator
<code>al</code> provided.<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(<br>
&nbsp;&nbsp;multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp;&amp; x,<br>
&nbsp;&nbsp;const allocator_type&amp; al);</code>
<blockquote>
<b>Requires:</b> <code>Value</code> is <code>MoveInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Constructs a <code>multi_index_container</code> by transferring/moving
the elements of <code>x</code>, copying its internal objects (those specified
in <code>ctor_args_list</code>) and using a copy of the allocator
<code>al</code> provided. If <code>x.get_allocator()==al</code>, elements are transferred
(no constructions involved), otherwise they are move constructed from <code>x</code>.<br>
<b>Postconditions:</b> If <code>x==y</code> just
before the movement, <code>*this==y</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
<b>Complexity:</b> Constant if <code>x.get_allocator()==al</code>, otherwise
<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>
@@ -674,8 +821,14 @@ contained. The order in which the elements are destroyed is not specified.<br>
&nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x);</code>
<blockquote>
Replaces the elements and internal objects of the <code>multi_index_container</code>
with copies from <code>x</code>.<br>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Replaces the elements and internal objects (those specified
in <code>ctor_args_list</code>) of the <code>multi_index_container</code>
with copies from <code>x</code>. The internal allocator is replaced with a
copy of <code>x.get_allocator()</code> if and only if
<code>std::allocator_traits&lt;allocator_type>::propagate_on_container_copy_assignment::value</code>
is <code>true</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>
@@ -685,7 +838,53 @@ C(x.size()))</code>.<br>
of the types of <code>ctor_args_list</code> do not throw.
</blockquote>
<code>allocator_type get_allocator()const;</code>
<code>multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; operator=(<br>
&nbsp;&nbsp;multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> If <code>std::allocator_traits&lt;allocator_type>::propagate_on_container_move_assignment::value</code>
is <code>true</code>, <code>Value</code> is <code>MoveInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Replaces the elements of <code>multi_index_container</code>
with those of <code>x</code> or with copies move-constructed from those of <code>x</code>.
Replaces the internal objects (those specified
in <code>ctor_args_list</code>) with copies from the
corresponding objects in <code>x</code>. Replaces the internal allocator with a
copy of <code>x.get_allocator()</code> if and only if
<code>std::allocator_traits&lt;allocator_type>::propagate_on_container_move_assignment::value</code>
is <code>true</code>.
Elements of <code>x</code> are transferred (no constructions involved) if and only if
<code>x.get_allocator()</code> is copied or is equal to the previous value of the internal
allocator.
<br>
<b>Postconditions:</b> If <code>x==y</code> just
before the movement, <code>*this==y</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
<b>Returns:</b> <code>*this</code>.<br>
<b>Complexity:</b> <code>O(n)</code> if elements of <code>x</code> are transferred,
otherwise <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>multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; operator=(<br>
&nbsp;&nbsp;std::initializer_list&lt;Value&gt; list);</code>
<blockquote>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Replaces the elements of the <code>multi_index_container</code>
with copies of the elements of <code>list</code>, inserted in the specified order.
Insertion of each element may or may not succeed depending
on the acceptance by all the indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> <code>*this</code>.<br>
<b>Complexity:</b> <code>O(n + I(m))</code>, where <code>m</code> is the
number of elements of <code>list</code>.<br>
<b>Exception safety:</b> Strong, provided the copy and assignment operations
of the types of <code>ctor_args_list</code> do not throw.
</blockquote>
<code>allocator_type get_allocator()const noexcept;</code>
<blockquote>
Returns a copy of the <code>allocator_type</code> object used to construct
@@ -695,27 +894,25 @@ the <code>multi_index_container</code>.<br>
<h4><a name="index_retrieval">Index retrieval operations</a></h4>
<code>template&lt;int N> typename nth_index&lt;N>::type&amp; get();</code>
<code>template&lt;int N> typename nth_index&lt;N>::type&amp; get()noexcept;</code>
<blockquote>
<b>Requires:</b> <code>0 &lt;= N &lt; I</code>.<br>
<b>Requires:</b> <code>0 &lt;= N &lt; I-1</code>.<br>
<b>Effects:</b> Returns a reference to the
<code>nth_index&lt;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&lt;int N> const typename nth_index&lt;N>::type&amp; get()const;</code>
<code>template&lt;int N> const typename nth_index&lt;N>::type&amp; get()const noexcept;</code>
<blockquote>
<b>Requires:</b> <code>0 &lt;= N &lt; I</code>.<br>
<b>Requires:</b> <code>0 &lt;= N &lt; I-1</code>.<br>
<b>Effects:</b> Returns a <code>const</code> reference to the
<code>nth_index&lt;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&lt;typename Tag> typename index&lt;Tag>::type&amp; get()</code>
<code>template&lt;typename Tag> typename index&lt;Tag>::type&amp; get()noexcept;</code>
<blockquote>
<b>Requires:</b> <code>Tag</code> is such that <code>index&lt;Tag>::type</code>
@@ -724,10 +921,9 @@ is valid.<br>
<code>index&lt;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&lt;typename Tag> const typename index&lt;Tag>::type&amp; get()const;</code>
<code>template&lt;typename Tag> const typename index&lt;Tag>::type&amp; get()const noexcept;</code>
<blockquote>
<b>Requires:</b> <code>Tag</code> is such that <code>index&lt;Tag>::type</code>
@@ -736,7 +932,6 @@ is valid.<br>
<code>index&lt;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>
@@ -754,60 +949,60 @@ are <i>equivalent</i> if:
</p>
<code>template&lt;int N,typename IteratorType><br>
typename nth_index_iterator&lt;N>::type project(IteratorType it);</code>
typename nth_index&lt;N>::type::iterator project(IteratorType it);</code>
<blockquote>
<b>Requires:</b> <code>0 &lt;= N &lt; I</code>. <code>IteratorType</code>
<b>Requires:</b> <code>0 &lt;= N &lt; I-1</code>. <code>IteratorType</code>
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
iterator of some index of <code>*this</code> (i.e. does not refer to some
other <code>multi_index_container</code>.)<br>
<b>Effects:</b> Returns an <code>nth_index_iterator&lt;N>::type</code> iterator
other <code>multi_index_container</code>).<br>
<b>Effects:</b> Returns an <code>nth_index&lt;N>::type::iterator</code>
equivalent to <code>it</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.
</blockquote>
<code>template&lt;int N,typename IteratorType><br>
typename nth_index_const_iterator&lt;N>::type project(IteratorType it)const;</code>
typename nth_index&lt;N>::type::const_iterator project(IteratorType it)const;</code>
<blockquote>
<b>Requires:</b> <code>0 &lt;= N &lt; I</code>. <code>IteratorType</code>
<b>Requires:</b> <code>0 &lt;= N &lt; I-1</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&lt;N>::type</code>
iterator equivalent to <code>it</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.
</blockquote>
<code>template&lt;typename Tag,typename IteratorType><br>
typename index_iterator&lt;Tag>::type project(IteratorType it);</code>
<blockquote>
<b>Requires:</b> <code>Tag</code> is such that
<code>index_iterator&lt;Tag>::type</code> is valid. <code>IteratorType</code>
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
iterator of some index of <code>*this</code> (i.e. does not refer to some
other <code>multi_index_container</code>.)<br>
<b>Effects:</b> Returns an <code>index_iterator&lt;Tag>::type</code> iterator
<b>Effects:</b> Returns an <code>nth_index&lt;N>::type::const_iterator</code>
equivalent to <code>it</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.
</blockquote>
<code>template&lt;typename Tag,typename IteratorType><br>
typename index_const_iterator&lt;Tag>::type project(IteratorType it)const;</code>
typename index&lt;Tag>::type::iterator project(IteratorType it);</code>
<blockquote>
<b>Requires:</b> <code>Tag</code> is such that
<code>index_const_iterator&lt;Tag>::type</code> is valid. <code>IteratorType</code>
<code>index&lt;Tag>::type</code> is valid. <code>IteratorType</code>
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
iterator of some index of <code>*this</code> (i.e. does not refer to some
other <code>multi_index_container</code>).<br>
<b>Effects:</b> Returns an <code>index&lt;Tag>::type::iterator</code>
equivalent to <code>it</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.
</blockquote>
<code>template&lt;typename Tag,typename IteratorType><br>
typename index&lt;Tag>::type::const_iterator project(IteratorType it)const;</code>
<blockquote>
<b>Requires:</b> <code>Tag</code> is such that
<code>index&lt;Tag>::type</code> is valid. <code>IteratorType</code>
belongs to <code>const_iterator_type_list</code> or
<code>iterator_type_list</code>. <code>it</code> is a valid
(constant or non-constant) iterator of some index of <code>*this</code>
(i.e. does not refer to some other <code>multi_index_container</code>.)<br>
<b>Effects:</b> Returns an <code>index_const_iterator&lt;Tag>::type</code>
(i.e. does not refer to some other <code>multi_index_container</code>).<br>
<b>Effects:</b> Returns an <code>index&lt;Tag>::type::const_iterator</code>
iterator equivalent to <code>it</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.
@@ -831,8 +1026,7 @@ these, the following concepts are used. A type <code>T</code> is <i>serializable
archive (XML archive) and later retrieved from an input archive (XML archive) associated to
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>x'</code> is a <i>restored copy</i> of <code>x</code>. Given a binary predicate
<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
@@ -849,7 +1043,7 @@ 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>
each of the indices of <code>m</code> can impose other 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>
@@ -859,7 +1053,7 @@ 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>
each of the indices of <code>m'</code> can impose other requirements.<br>
<b>Exception safety:</b> Basic. If an exception is thrown, <code>ar</code> may be
left in an inconsistent state.
</blockquote>
@@ -878,9 +1072,9 @@ Index reference
<br>
<p>Revised May 30th 2005</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2026 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+526 -131
View File
@@ -5,6 +5,10 @@
<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">
<link rel="start" href="../index.html">
<link rel="prev" href="indices.html">
<link rel="up" href="index.html">
<link rel="next" href="hash_indices.html">
</head>
<body>
@@ -17,8 +21,8 @@ Index reference
<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
<div class="next_link"><a href="rnk_indices.html"><img src="../next.gif" alt="ranked indices" border="0"><br>
Ranked indices
</a></div><br clear="all" style="clear: all;">
<hr>
@@ -38,7 +42,9 @@ Hashed indices
<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="#iterators">Iterators</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#observers">Observers</a></li>
<li><a href="#set_operations">Set operations</a></li>
@@ -92,6 +98,8 @@ their associated <a href="#ord_indices">ordered index</a> classes.
<code>"boost/multi_index/ordered_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@@ -159,7 +167,7 @@ two different forms, according to whether a tag list for the index is provided o
<p>
If provided, <code>TagList</code> must be an instantiation of the class template
<a href="#tag"><code>tag</code></a>.
<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.
@@ -185,15 +193,17 @@ 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.
Except where noted or if the corresponding interface does not exist,
ordered indices (both unique and non-unique) satisfy the C++ requirements
for associative containers at <b>[associative.reqmts]</b>
(supporting unique and equivalent keys, respectively).
Iterators (including to the end of the index) and pointers and references to an element
remain valid during the lifetime of the associated container (which can change
upon swapping), or until the referred-to element is erased or extracted;
pointers and references to an extracted element, but not so for iterators,
become valid again once the element is re-inserted.
We only provide descriptions of those types and operations that
do not exactly conform to or are not mandated by the standard requirements.
</p>
<blockquote><pre>
@@ -201,7 +211,7 @@ requirements for these types of containers.
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=keyword>namespace</span><span class=special>{</span> <b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=special>}</span> <span class=comment>// see range()</span>
<b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=comment>// see range()</span>
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
@@ -217,7 +227,8 @@ requirements for these types of containers.
<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>&lt;</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>&gt;</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>&gt;</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
@@ -231,48 +242,85 @@ requirements for these types of containers.
std::reverse_iterator&lt;iterator&gt;</b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>equivalent to
std::reverse_iterator&lt;const_iterator&gt;</b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>same as owning container </b><span class=identifier>node_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>following [container.insert.return] spec </b><span class=identifier>insert_return_type</span><span class=special>;</span>
<span class=comment>// construct/copy/destroy:</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</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=identifier>iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<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>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</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=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// modifiers:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>emplace_hint</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>insert_return_type</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>node_type</span><span class=special>&amp;&amp;</span> <span class=identifier>nh</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>node_type</span><span class=special>&amp;&amp;</span> <span class=identifier>nh</span><span class=special>);</span>
<span class=keyword>void</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>node_type</span> <span class=identifier>extract</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>node_type</span> <span class=identifier>extract</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>size_type</span> <span class=identifier>erase</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</span> <span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span><span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>merge</span><span class=special>(</span>
<span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span>
<span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_iterator</span> <span class=identifier>first</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_iterator</span> <span class=identifier>last</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>
@@ -292,6 +340,11 @@ requirements for these types of containers.
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>contains</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>contains</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
@@ -390,9 +443,9 @@ 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>hinted insertion: <code>h(n)=1</code> (amortized constant) if the hint element
is immediately after the point of insertion, <code>h(n)=log(n)</code> otherwise,</li>
<li>deletion: <code>d(n)=1</code> (amortized constant),</li>
<li>replacement: <code>r(n)=1</code> (constant) if the element position does not
change, <code>r(n)=log(n)</code> otherwise,</li>
<li>modifying: <code>m(n)=1</code> (constant) if the element position does not
@@ -410,7 +463,7 @@ following types:
<ul>
<li><code>Value</code> from <code>multi_index_container</code>,</li>
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
<li><code>TagList</code> from the index specifier (if provided),</li>
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag&lt;&gt;</code> is assumed),</li>
<li><code>KeyFromValue</code> from the index specifier,</li>
<li><code>Compare</code> from the index specifier.</li>
</ul>
@@ -419,11 +472,20 @@ following types:
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>.
<code>CopyConstructible</code> binary predicate inducing a strict weak order
on elements of <code>KeyFromValue::result_type</code>.
</p>
<h4><a name="types">Nested types</a></h4>
<code>iterator<br>
const_iterator</code>
<blockquote>
These types depend only on <code>node_type</code> and the position of
the index in the <code>multi_index_container</code>.
</blockquote>
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
<p>
@@ -444,11 +506,91 @@ 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&lt;iterator,bool> insert(const value_type&amp; x);</code>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="modifiers">Modifiers</a></h4>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
<li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful insertion,
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
points to an element that caused the insertion to be banned. Note that more than
one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
iterator emplace_hint(iterator position, Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
<li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<code>position</code> is used as a hint to improve the efficiency of the
operation. If successful, insertion happens as close as possible to the
location just prior to <code>position</code>.<br>
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
element. Otherwise, an iterator to an element that caused the insertion to be
banned. Note that more than one element can be causing insertion not to be
allowed.<br>
<b>Complexity:</b> <code>O(H(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
@@ -466,10 +608,16 @@ one element can be causing insertion not to be allowed.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>iterator insert(iterator position,const value_type&amp; x);</code>
<code>iterator insert(iterator position,const value_type&amp; x);</code><br>
<code>iterator insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
@@ -479,7 +627,8 @@ the index belongs if
<code>multi_index_container</code>.</li>
</ul>
<code>position</code> is used as a hint to improve the efficiency of the
operation.<br>
operation. If successful, insertion happens as close as possible to the
location just prior to <code>position</code>.<br>
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
element. Otherwise, an iterator to an element that caused the insertion to be
banned. Note that more than one element can be causing insertion not to be
@@ -492,30 +641,125 @@ allowed.<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>.
<b>Requires:</b> <code>InputIterator</code> is an input iterator.
<code>value_type</code> is <code>EmplaceConstructible</code> into
<code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.</br>
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>iterator</span> <span class=identifier>hint</span><span class=special>=</span><span class=identifier>end</span><span class=special>();</span>
<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>
For each element of [<code>first</code>, <code>last</code>), in this
order, inserts it into the <code>multi_index_container</code>
to which this 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>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>void erase(iterator position);</code>
<code>void insert(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.</br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>())</span><span class=special>;</span>
</pre></blockquote>
</blockquote>
<code>insert_return_type insert(node_type&amp;&amp; nh);</code>
<blockquote>
<b>Requires:</b> <code>nh.empty() || get_allocator()==nh.get_allocator()</code>.<br>
<b>Effects:</b> Does nothing if <code>nh</code> is empty; otherwise,
inserts the node owned by <code>nh</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>Postconditions:</b> <code>nh</code> is empty.<br>
<b>Returns:</b> A value <code>p</code> of type <code>insert_return_type</code>.
If <code>nh</code> is empty, <code>p.position</code> is <code>end()</code>,
<code>p.inserted</code> is <code>false</code> and <code>p.node</code> is empty;
on successful insertion, <code>p.position</code> points to the element inserted,
<code>p.inserted</code> is <code>true</code> and <code>p.node</code>
is empty;
if the insertion failed, <code>p.position</code> points to an element that caused
the insertion to be banned, <code>p.inserted</code> is <code>false</code> and
<code>p.node</code> owns the original node.
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. If an exception
is thrown, <code>nh</code> is not changed.<br>
</blockquote>
<code>iterator insert(const_iterator position,node_type&amp;&amp; nh);</code>
<blockquote>
<b>Requires:</b> <code>nh.empty() || get_allocator()==nh.get_allocator()</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Does nothing if <code>nh</code> is empty; otherwise,
inserts the node owned by <code>nh</code> into the
<code>multi_index_container</code> to which the index belongs if
<ul>
<li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<code>position</code> is used as a hint to improve the efficiency of the
operation. If successful, insertion happens as close as possible to the
location just prior to <code>position</code>.<br>
<b>Postconditions:</b> <code>nh</code> is empty if insertion succeeds,
and is not changed otherwise.<br>
<b>Returns:</b> <code>end()</code> if <code>nh</code> is empty.
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. If an exception
is thrown, <code>nh</code> is not changed.<br>
</blockquote>
<code>node_type extract(const_iterator position);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.<br>
<b>Effects:</b> Extracts the node of the element pointed to by <code>position</code>.<br>
<b>Returns:</b> A node handle owning the extracted node.<br>
<b>Complexity:</b> <code>O(D(n))</code>.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<code>node_type extract(const key_type&amp; x);</code>
<blockquote>
<b>Effects:</b> Extracts the node of the first element
with key equivalent to <code>x</code>, if there is any.<br>
<b>Returns:</b> A node handle owning the extracted node, or empty otherwise.<br>
<b>Complexity:</b> <code>O(log(n) + D(n))</code>.<br>
<b>Exception safety:</b> Strong.<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>
@@ -530,22 +774,26 @@ the number of elements deleted.<br>
<b>Exception safety:</b> Basic.<br>
</blockquote>
<code>void erase(iterator first,iterator last);</code>
<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&amp; x);</code></a>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.</br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if, for the value <code>x</code>
@@ -556,7 +804,8 @@ the index belongs if, for the value <code>x</code>
<code>multi_index_container</code>.</li>
</ul>
<b>Postconditions:</b> Validity of <code>position</code> is preserved
in all cases.<br>
in all cases. If the key of the new value is equivalent to that of the
replaced value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the replacement took place,
<code>false</code> otherwise.<br>
<b>Complexity:</b> <code>O(R(n))</code>.<br>
@@ -569,11 +818,14 @@ belongs remains in its original state.
<code>template&lt;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
<b>Requires:</b> <code>mod</code> is a unary function object
accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
iterator of the index.
The execution of <code>mod(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, does not invoke any operation of the
<code>multi_index_container</code> after <code>e</code> is directly modified
or, before modification, if the operation would invalidate <code>position</code>.<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
@@ -585,46 +837,182 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
</ul>
If the rearrangement fails, the element is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the
operation succeeds.<br>
operation succeeds. If the key of the modified value is equivalent to that of the
original value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Basic. If an exception is thrown by some
user-provided operation (except possibly <code>mod</code>), then
user-provided operation (including <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
objects accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The execution of <code>mod(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, does not invoke any operation of the
<code>multi_index_container</code> after <code>e</code> is directly modified
or, before modification, if the operation would invalidate <code>position</code>.
<code>back(e)</code> does not invoke any operation of the
<code>multi_index_container</code>.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, <code>back(e)</code> is invoked: if the resulting value
of <code>e</code> is consistent with its original position and constraints in all
indices, the element is kept, otherwise it is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.
If the key of the modified value is equivalent to that of the
original value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>mod</code> or <code>back</code> throw an
exception or <code>back(e)</code> fails to properly restore the element or there is
a throwing user-provided operation after invoking <code>back(e)</code>, in which cases
the modified element is erased. If <code>back</code>
throws inside the handling code executing after some other user-provided
operation has thrown, it is the exception generated by <code>back</code> that
is rethrown.
</blockquote>
<a name="modify_key">
<code>template&lt;typename Modifier> bool modify_key(iterator position,Modifier mod);</code></a>
<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
from <code>value_type</code>. <code>mod</code> is a
unary function object accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
<b>Effects:</b> Calls <code>mod(k)</code> where <code>k</code> is the key
obtained by the internal <code>KeyFromValue</code> object of the index from
the element pointed to by <code>position</code>, and rearranges
<code>*position</code> into all the indices of the <code>multi_index_container</code>.
Rearrangement is successful if
iterator of the index.
The execution of <code>mod(k)</code>, where <code>k</code> is the key of the element
pointed to by <code>position</code>, does not invoke any operation of the
<code>multi_index_container</code> after <code>k</code> is directly modified
or, before modification, if the operation would invalidate <code>position</code>.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod')</code>,
with <code>mod'</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code>, where
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>mod</code> and <code>back</code>
are unary function objects accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The execution of <code>mod(k)</code>, where <code>k</code> is the key of the element
pointed to by <code>position</code>, does not invoke any operation of the
<code>multi_index_container</code> after <code>k</code> is directly modified
or, before modification, if the operation would invalidate <code>position</code>.
<code>back(k)</code> does not invoke any operation of the
<code>multi_index_container</code>.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>,
with <code>mod'</code> and <code>back</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
<code>back'(x)</code> is the same as <code>back(key(x))</code>, where
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<a name="merge"><code>template&lt;typename Index&gt; void merge(Index&amp;&amp; x);</code></a>
<blockquote>
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
<a href="multi_index_container.html#node_type">node-compatible</a>
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>merge</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>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>
template&lt;typename Index&gt; std::pair&lt;iterator,bool&gt; merge(<br>
&nbsp;&nbsp;Index&amp;&amp; x,typename std::remove_reference_t&lt;Index&gt;::const_iterator i);
</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
<a href="multi_index_container.html#node_type">node-compatible</a>
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.
<code>i</code> is a valid dereferenceable iterator of <code>x</code>.<br>
<b>Effects:</b> Does nothing if the source and destination containers are the same;
otherwise, transfers the node of the element referred to by <code>i</code> into the
<code>multi_index_container</code> to which the destination index belongs 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
<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>
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.
Note that no element is copied or destroyed in the process.<br>
<b>Postconditions:</b> If transfer succeeds, for any index in the source container
having the same <code>iterator</code>/<code>const_iterator</code> types as the corresponding
index in the destination container, iterators referring to <code>*i</code>
remain valid and behave as iterators of the destination index.<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 transfer took place or the source and destination
containers are the same. If <code>p.second</code> is <code>true</code>,
<code>p.first</code> points to <code>*i</code>; 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> If the source and destination containers are the same,
constant; otherwise, <code>O(I(n)+D(x.size()))</code>.<br>
<b>Exception safety:</b> If the source and destination containers are the same,
<code>nothrow</code>; otherwise strong.
</blockquote>
<code>
template&lt;typename Index&gt; void merge(<br>
&nbsp;&nbsp;Index&amp;&amp; x,<br>
&nbsp;&nbsp;typename std::remove_reference_t&lt;Index&gt;::const_iterator first,<br>
&nbsp;&nbsp;typename std::remove_reference_t&lt;Index&gt;::const_iterator last);
</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
<a href="multi_index_container.html#node_type">node-compatible</a>
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.
[<code>first</code>,<code>last</code>) is a valid range of <code>x</code>.<br>
<b>Effects:</b> Does nothing if the source and destination containers are the same;
otherwise, for each node in [<code>first</code>,<code>last</code>), in this order,
the node is transferred to the <code>multi_index_container</code> to which the
destination 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>
Note that no element is copied or destroyed in the process.<br>
<b>Postconditions:</b> For any index in the source container having the same
<code>iterator</code>/<code>const_iterator</code> types as the corresponding
index in the destination container, iterators referring to the transferred elements
remain valid and behave as iterators of the destination index.<br>
<b>Complexity:</b> If the source and destination containers are the same,
constant; otherwise, <code>O(m*(I(n+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 the source and destination containers are the same,
<code>nothrow</code>; otherwise basic.
</blockquote>
<h4><a name="observers">Observers</a></h4>
@@ -646,10 +1034,7 @@ the index.<br>
<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>,
<b>[associative.reqmts]</b>, 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
@@ -659,20 +1044,14 @@ 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>,
Consider a binary predicate <code>Compare</code> inducing a strict
weak order 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>,
<li><code>CompatibleCompare</code> is a binary predicate 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>,
<li><code>CompatibleCompare</code> is a binary predicate 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
@@ -707,7 +1086,7 @@ interpretations.
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.</br>
<code>key_compare</code>.<br>
<b>Effects:</b> Returns a pointer to an element whose key is equivalent to
<code>x</code>, or <code>end()</code> if such an element does not exist.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
@@ -719,19 +1098,19 @@ iterator find(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.</br>
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Returns a pointer to an element whose key is equivalent to
<code>x</code>, or <code>end()</code> if such an element does not exist.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey> size_type<br>
count(const CompatibleKey&amp; x)const;
<code>template&lt;typename CompatibleKey><br>
size_type count(const CompatibleKey&amp; x)const;
</code>
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.</br>
<code>key_compare</code>.<br>
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
<b>Complexity:</b> <code>O(log(n) + count(x))</code>.<br>
</blockquote>
@@ -742,18 +1121,40 @@ size_type count(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)con
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.</br>
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
<b>Complexity:</b> <code>O(log(n) + count(x,comp))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
bool contains(const CompatibleKey&amp; x)const;
</code>
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.<br>
<b>Effects:</b> Returns <code>true</code> iff there is some element with key equivalent to <code>x</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
bool contains(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Returns <code>true</code> iff there is some element with key equivalent to <code>x</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
iterator lower_bound(const CompatibleKey&amp; x)const;
</code>
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.</br>
<code>key_compare</code>.<br>
<b>Effects:</b> Returns an iterator pointing to the first element with
key not less than <code>x</code>, or <code>end()</code> if such an element does
not exist.<br>
@@ -766,7 +1167,7 @@ iterator lower_bound(const CompatibleKey&amp; x,const CompatibleCompare&amp; com
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.</br>
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Returns an iterator pointing to the first element with
key not less than <code>x</code>, or <code>end()</code> if such an element does
not exist.<br>
@@ -779,7 +1180,7 @@ iterator upper_bound(const CompatibleKey&amp; x)const;
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.</br>
<code>key_compare</code>.<br>
<b>Effects:</b> Returns an iterator pointing to the first element with
key greater than <code>x</code>, or <code>end()</code> if such an element does
not exist.<br>
@@ -792,7 +1193,7 @@ iterator upper_bound(const CompatibleKey&amp; x,const CompatibleCompare&amp; com
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.</br>
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Returns an iterator pointing to the first element with
key greater than <code>x</code>, or <code>end()</code> if such an element does
not exist.<br>
@@ -806,19 +1207,19 @@ std::pair&lt;iterator,iterator> equal_range(<br>
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.</br>
<code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>make_pair(lower_bound(x),upper_bound(x))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
std::pair&lt;iterator,iterator> equal_range(</br>
std::pair&lt;iterator,iterator> equal_range(<br>
&nbsp;&nbsp;const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.</br>
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to
<code>make_pair(lower_bound(x,comp),upper_bound(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
@@ -835,15 +1236,11 @@ 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
Consider a binary predicate <code>Compare</code> inducing a strict
weak order 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><code>LowerBounder</code> is a predicate over <code>Key</code>,</li>
<li>if <code>lower(k1)</code> and <code>!comp(k2,k1)</code> then
<code>lower(k2)</code>,</li>
</ol>
@@ -852,9 +1249,7 @@ for every <code>lower</code> of type <code>LowerBounder</code>,
<code>k2</code> of type <code>Key</code>. Similarly, an <i>upper bounder</i>
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><code>UpperBounder</code> is a predcate over <code>Key</code>,</li>
<li>if <code>upper(k1)</code> and <code>!comp(k1,k2)</code> then
<code>upper(k2)</code>,</li>
</ol>
@@ -870,7 +1265,7 @@ std::pair&lt;iterator,iterator> range(<br>
<blockquote>
<b>Requires:</b> <code>LowerBounder</code> and <code>UpperBounder</code> are
a lower and upper bounder of <code>key_compare</code>, respectively.</br>
a lower and upper bounder of <code>key_compare</code>, respectively.<br>
<b>Effects:</b> Returns a pair of iterators pointing to the beginning and one
past the end of the subsequence of elements satisfying <code>lower</code> and
<code>upper</code> simultaneously. If no such elements exist, the iterators
@@ -908,7 +1303,7 @@ input archive (XML archive) <code>ar</code>.
<b>Requires:</b> Additionally to the general requirements, <code>value_comp()</code>
must be serialization-compatible with <code>m.get&lt;i&gt;().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
<b>Postconditions:</b> On successful loading, each of the elements of
[<code>begin()</code>, <code>end()</code>) is a restored copy of the corresponding
element in [<code>m.get&lt;i&gt;().begin()</code>, <code>m.get&lt;i&gt;().end()</code>).
</blockquote>
@@ -925,11 +1320,11 @@ 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
<b>Postconditions:</b> On successful 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.
and the restored <code>it'</code> an <code>iterator</code>, or vice versa.
</blockquote>
<hr>
@@ -940,15 +1335,15 @@ Index reference
<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
<div class="next_link"><a href="rnk_indices.html"><img src="../next.gif" alt="ranked indices" border="0"><br>
Ranked indices
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised February 7th 2005</p>
<p>Revised February 5th 2022</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2022 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
File diff suppressed because it is too large Load Diff
+712
View File
@@ -0,0 +1,712 @@
<!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 - Ranked indices reference</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<link rel="start" href="../index.html">
<link rel="prev" href="indices.html">
<link rel="up" href="index.html">
<link rel="next" href="hash_indices.html">
</head>
<body>
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Ranked 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="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="#rnk_index_fwd_synopsis">Header
<code>"boost/multi_index/ranked_index_fwd.hpp"</code> synopsis</a></li>
<li><a href="#synopsis">Header
<code>"boost/multi_index/ranked_index.hpp"</code> synopsis</a>
<ul>
<li><a href="#unique_non_unique">
Index specifiers <code>ranked_unique</code> and <code>ranked_non_unique</code>
</a></li>
<li><a href="#rnk_indices">Ranked 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="#set_operations">Set operations</a></li>
<li><a href="#rank_operations">Rank operations</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>
<a name="rnk_index_fwd_synopsis">Header
<a href="../../../../boost/multi_index/ranked_index_fwd.hpp">
<code>"boost/multi_index/ranked_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 ranked_unique and ranked_non_unique</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>consult ranked_unique reference for arguments</b><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>ranked_unique</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>consult ranked_non_unique reference for arguments</b><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>ranked_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>&lt;</span><b>implementation defined</b><span class=special>&gt;</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>ranked_index_fwd.hpp</code> provides forward declarations for index specifiers
<a href="#unique_non_unique"><code>ranked_unique</code> and <code>ranked_non_unique</code></a> and
their associated <a href="#rnk_indices">ranked index</a> classes.
</p>
<h2>
<a name="synopsis">Header
<a href="../../../../boost/multi_index/ranked_index.hpp">
<code>"boost/multi_index/ranked_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=comment>// index specifiers ranked_unique and ranked_non_unique</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>consult ranked_unique reference for arguments</b><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>ranked_unique</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>consult ranked_non_unique reference for arguments</b><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>ranked_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>&lt;</span><b>implementation defined</b><span class=special>&gt;</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 ==,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</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>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</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>&lt;</span><b>implementation defined</b><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&amp;</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>ranked_unique</code> and <code>ranked_non_unique</code>
</a></h3>
<p>
These <a href="indices.html#index_specification">index specifiers</a> allow
for insertion of <a href="#rnk_indices">ranked indices</a> without and with
allowance of duplicate elements, respectively. The syntax of <code>ranked_unique</code>
and <code>ranked_non_unique</code> coincide, thus we describe them in a grouped manner.
<code>ranked_unique</code> and <code>ranked_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>&lt;</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>&lt;</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>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>&lt;</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_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="#rnk_indices">ranked indices</a> reference section for further
explanations on their acceptable type values.
</p>
<h3><a name="rnk_indices">Ranked indices</a></h3>
<p>
Ranked indices are a variation of <a href="ord_indices.html">ordered indices</a>
providing additional capabilities for calculation of and access by rank; the <i>rank</i> of an element is the
distance to it from the beginning of the index. Besides this extension, ranked indices replicate the
public interface of ordered indices with the difference, complexity-wise, that
<a href="#complexity_signature">hinted insertion</a> and <a href="#complexity_signature">deletion</a>
are done in logarithmic rather than constant time. Also, execution times and memory consumption are
expected to be poorer due to the internal bookkeeping needed to maintain rank-related information
(an exception being <a href="#count"><code>count</code> operations</a>, which are actually faster).
As with ordered indices, ranked indices can be unique (no duplicate elements are allowed)
or non-unique: either version is associated to a different index specifier, but
the interface of both index types is the same.
</p>
<p>
In what follows, we only describe the extra operations provided by ranked indices or those
operations with improved performance: for the
rest refer to the <a href="ord_indices.html#ord_indices">documentation</a> for ordered
indices, bearing in mind the occasional differences in complexity.
</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>
<b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=comment>// see range_rank()</span>
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>implementation defined: dependent on types Value, Allocator,
TagList, KeyFromValue, Compare</b><span class=special>&gt;</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>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>&gt;</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
<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&lt;iterator&gt;</b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>equivalent to
std::reverse_iterator&lt;const_iterator&gt;</b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>same as owning container </b><span class=identifier>node_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>following [container.insert.return] spec </b><span class=identifier>insert_return_type</span><span class=special>;</span>
<span class=comment>// construct/copy/destroy:</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</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=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</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=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// modifiers:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>emplace_hint</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>insert_return_type</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>node_type</span><span class=special>&amp;&amp;</span> <span class=identifier>nh</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>node_type</span><span class=special>&amp;&amp;</span> <span class=identifier>nh</span><span class=special>);</span>
<span class=identifier>node_type</span> <span class=identifier>extract</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>node_type</span> <span class=identifier>extract</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>size_type</span> <span class=identifier>erase</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</span> <span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span><span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>merge</span><span class=special>(</span>
<span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span>
<span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_iterator</span> <span class=identifier>first</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_iterator</span> <span class=identifier>last</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>contains</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>contains</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</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>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt;</span> <span class=identifier>equal_range</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt;</span> <span class=identifier>equal_range</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</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>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt;</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=comment>// rank operations:</span>
<span class=identifier>iterator</span> <span class=identifier>nth</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>rank</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=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>find_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>find_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>lower_bound_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>lower_bound_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>upper_bound_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>upper_bound_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>&gt;</span> <span class=identifier>equal_range_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>&gt;</span> <span class=identifier>equal_range_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</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>&lt;</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>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>&gt;</span>
<span class=identifier>range_rank</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>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</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>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</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>()&amp;&amp;</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>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&lt;(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</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>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</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>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</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>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&gt;(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</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>&lt;</span><span class=identifier>x</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&gt;=(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</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>&lt;</span><span class=identifier>y</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&lt;=(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</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>&gt;</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>&lt;</span><b>implementation defined</b><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&amp;</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>
We follow the terminology described in the
<a href="indices.html#complexity_signature">complexity signature
section</a>. The complexity signature of ranked 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: <b><code>h(n)=log(n)</code></b>,</li>
<li>deletion: <b><code>d(n)=log(n)</code></b> ,</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>
<p>
These complexity guarantees are the same as those of
<a href="ord_indices.html#complexity_signature">ordered indices</a>
except for hinted insertion and deletion, which are <code>log(n)</code> here and amortized constant there.
</p>
<h4><a name="instantiation_types">Instantiation types</a></h4>
<p>Ranked 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>ranked_unique</code>
and <code>ranked_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, otherwise <code>tag&lt;&gt;</code> is assumed),</li>
<li><code>KeyFromValue</code> from the index specifier,</li>
<li><code>Compare</code> from the index specifier.</li>
</ul>
These types are subject to the same requirements as specified for
<a href="ord_indices.html#instantiation_types">ordered indices</a>.
</p>
<h4><a name="types">Nested types</a></h4>
<code>iterator<br>
const_iterator</code>
<blockquote>
These types depend only on <code>node_type</code> and the position of
the index in the <code>multi_index_container</code>.
</blockquote>
<h4><a name="set_operations">Set operations</a></h4>
<p>
See the documentation of ordered indices for an explanation of the notions of
<a href="ord_indices.html#set_operations"><i>compatible extension</i> and
<i>compatible key</i></a>, which are referred to below.
</p>
<a name="count">
<code>template&lt;typename CompatibleKey><br>
size_type count(const CompatibleKey&amp; x)const;
</code></a>
<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))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
size_type count(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<h4><a name="rank_operations">Rank operations</a></h4>
<p>
The <i>rank</i> of an iterator <code>it</code> of a given container <code>c</code> (and,
by extension, of the element it points to if the iterator is dereferenceable)
is <code>std::distance(c.begin(),it)</code>.
</p>
<p>
See the documentation of ordered indices for an explanation of the notions of
<a href="ord_indices.html#set_operations"><i>compatible extension</i>,
<i>compatible key</i></a>,
<a href="ord_indices.html#range_operations"><i>lower bounder</i> and <i>upper bounder</i></a>, which are
referred to below.
</p>
<code>iterator nth(size_type n)const;</code>
<blockquote>
<b>Effects:</b> Returns an iterator with rank <code>n</code>,
or <code>end()</code> if <code>n&gt;=size()</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>size_type rank(iterator position)const;
</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Returns the rank of <code>position</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey> size_type find_rank(const CompatibleKey&amp; 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>rank(find(k))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
size_type find_rank(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(find(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
size_type lower_bound_rank(const CompatibleKey&amp; 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>rank(lower_bound(x))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
size_type lower_bound_rank(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(lower_bound(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
size_type upper_bound_rank(const CompatibleKey&amp; 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>rank(upper_bound(x))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
size_type upper_bound_rank(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(upper_bound(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
std::pair&lt;size_type,size_type> equal_range_rank(<br>
&nbsp;&nbsp;const CompatibleKey&amp; 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_rank(x),upper_bound_rank(x))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
std::pair&lt;size_type,size_type> equal_range_rank(<br>
&nbsp;&nbsp;const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to
<code>make_pair(lower_bound_rank(x,comp),upper_bound_rank(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename LowerBounder,typename UpperBounder><br>
std::pair&lt;size_type,size_type> range_rank(<br>
&nbsp;&nbsp;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> Equivalent to
<blockquote><pre>
<span class=keyword>auto</span> <span class=identifier>p</span><span class=special>=</span><span class=identifier>range</span><span class=special>(</span><span class=identifier>lower</span><span class=special>,</span><span class=identifier>upper</span><span class=special>);</span>
<span class=keyword>return</span> <span class=identifier>make_pair</span><span class=special>(</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>first</span><span class=special>),</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>second</span><span class=special>));</span>
</pre></blockquote>
<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>
The prerequisites and postconditions associated to serialization of
<code>multi_index_container</code>s with ranked indices are exactly the same
as those of <a href="ord_indices.html#serialization">ordered indices</a>.
<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="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 February 5th 2022</p>
<p>&copy; Copyright 2003-2022 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>
+471 -174
View File
@@ -5,6 +5,10 @@
<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">
<link rel="start" href="../index.html">
<link rel="prev" href="hash_indices.html">
<link rel="up" href="index.html">
<link rel="next" href="rnd_indices.html">
</head>
<body>
@@ -17,8 +21,8 @@ Hashed indices
<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
<div class="next_link"><a href="rnd_indices.html"><img src="../next.gif" alt="random access indices" border="0"><br>
Random access indices
</a></div><br clear="all" style="clear: all;">
<hr>
@@ -36,11 +40,13 @@ Key extraction
<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="#iterators">Iterators</a></li>
<li><a href="#capacity">Capacity operations</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#list_operations">List operations</a></li>
<li><a href="#special_list_operations">Special list operations</a></li>
<li><a href="#rearrange_operations">Rearrange operations</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
</li>
@@ -87,6 +93,8 @@ its associated <a href="#seq_indices">sequenced index</a> class.
<code>"boost/multi_index/sequenced_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@@ -146,33 +154,33 @@ 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.
Iterators (including to the end of the index) and pointers and references to an element
remain valid during the lifetime of the associated container (which can change
upon swapping), or until the referred-to element is erased or extracted;
pointers and references to an extracted element, but not so for iterators,
become valid again once the element is re-inserted.
</p>
<p>
There are a number of differences with respect to <code>std::lists</code>:
Except where noted or if the corresponding interface does not exist, sequenced
indices verify the same container requirements as <code>std::list</code>:
we only provide descriptions of those types and operations that are either not
present in <code>std::list</code> or behave differently. Some of the
most important differences are:
<ul>
<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>The complexity of some operations, notably insertion and deletion, differ
from those of <code>std::list</code>.
</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
in place 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>
@@ -188,50 +196,63 @@ types of containers.
<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=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>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> <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_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&lt;iterator&gt;</b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>equivalent to
std::reverse_iterator&lt;const_iterator&gt;</b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>same as owning container </b><span class=identifier>node_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>following [container.insert.return] spec </b><span class=identifier>insert_return_type</span><span class=special>;</span>
<span class=comment>// construct/copy/destroy:</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>value</span><span class=special>);</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</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=identifier>iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<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>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</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=keyword>noexcept</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=keyword>noexcept</span><span class=special>;</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>value_type</span><span class=special>());</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// access:</span>
@@ -240,32 +261,55 @@ types of containers.
<span class=comment>// modifiers:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace_front</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_front</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_front</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>pop_front</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace_back</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_back</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_back</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>pop_back</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>insert_return_type</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>node_type</span><span class=special>&amp;&amp;</span> <span class=identifier>nh</span><span class=special>);</span>
<span class=identifier>node_type</span> <span class=identifier>extract</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>()</span><span class=keyword>noexcept</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>&amp;</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>&amp;</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>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</span> <span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>splice</span><span class=special>(</span>
<span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>&gt;</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>&amp;</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=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_iterator</span> <span class=identifier>first</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special>&lt;</span><span class=identifier>Index</span><span class=special>&gt;::</span><span class=identifier>const_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>&amp;</span> <span class=identifier>value</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Predicate</span><span class=special>&gt;</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>
@@ -280,12 +324,13 @@ types of containers.
<span class=keyword>void</span> <span class=identifier>sort</span><span class=special>();</span>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>&gt;</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=keyword>void</span> <span class=identifier>reverse</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// relocate operations:</span>
<span class=comment>// rearrange 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=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span> <span class=keyword>void</span> <span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>);</span>
<span class=special>}</span>
<span class=comment>// index comparison:</span>
@@ -376,12 +421,22 @@ index specifier. Instantiations are dependent on the following types:
<ul>
<li><code>Value</code> from <code>multi_index_container</code>,</li>
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
<li><code>TagList</code> from the index specifier (if provided).</li>
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag&lt;&gt;</code> is assumed).</li>
</ul>
<code>TagList</code> must be an instantiation of
<a href="indices.html#tag"><code>tag</code></a>.
</p>
<h4><a name="types">Nested types</a></h4>
<code>iterator<br>
const_iterator</code>
<blockquote>
These types depend only on <code>node_type</code> and the position of
the index in the <code>multi_index_container</code>.
</blockquote>
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
<p>
@@ -402,17 +457,22 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code>template &lt;class InputIterator><br>
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>
@@ -420,6 +480,15 @@ index of the <code>multi_index_container</code> to which this index belongs.
</pre></blockquote>
</blockquote>
<code>void assign(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>assign</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>void assign(size_type n,const value_type&amp; value);</code>
<blockquote>
@@ -430,54 +499,127 @@ index of the <code>multi_index_container</code> to which this index belongs.
</pre></blockquote>
</blockquote>
<h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="capacity">Capacity operations</a></h4>
<code>void resize(size_type n,const value_type&amp; x=value_type());</code>
<code>void resize(size_type n);<br>
void resize(size_type n,const value_type&amp; x);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&gt;</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>n</span><span class=special>-</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span>
<span class=keyword>else</span> <span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&lt;</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>n</span><span class=special>,</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>DefaultInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> If <code>size()&lt;n</code>, tries to append <code>n-size()</code> default-inserted
elements (first version) or copies of <code>x</code> (second version) at the end of
the index. If <code>n&lt;size()</code>, erases the last <code>size()-n</code> elements.<br>
<b>Note:</b> If an expansion is requested, the size of the index is not guaranteed
to be <code>n</code> after this operation (other indices may ban insertions.)
to be <code>n</code> after this operation (other indices may ban insertions).
</blockquote>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_front(Args&amp;&amp;... args);</code>
<blockquote>
<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>Effects:</b>
<blockquote><pre>
<span class=identifier>emplace</span><span class=special>(</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
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&lt;iterator,bool> push_back(const value_type&amp; x);</code>
<code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_front(value_type&amp;&amp; x);</code>
<blockquote>
<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>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <span class=comment>// lvalue ref version</span>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>move</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
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&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_back(Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>emplace</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_back(value_type&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <span class=comment>// lvalue ref version</span>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>move</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(iterator position,Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful insertion,
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
points to an element that caused the insertion to be banned. Note that more than
one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion
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>
@@ -492,7 +634,6 @@ Note that more than one element can be causing insertion not to be allowed.<br>
<code>void insert(iterator position,size_type n,const value_type&amp; x);</code>
<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>&lt;</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span>
@@ -504,27 +645,70 @@ 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>InputIterator</code> is an input iterator.
<code>value_type</code> is
<code>EmplaceConstructible</code> into
<code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.</br>
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
</pre></blockquote>
For each element of [<code>first</code>, <code>last</code>), in this
order, inserts it before <code>position</code> if insertion is allowed by all
other indices of the <code>multi_index_container</code>.<br>
<b>Complexity:</b> <code>O(m*I(n+m))</code>, where <code>m</code> is the
number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> Basic.
</blockquote>
<code>void insert(iterator position,std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>insert_return_type insert(const_iterator position,node_type&amp;&amp; nh);</code>
<blockquote>
<b>Requires:</b> <code>nh.empty() || get_allocator()==nh.get_allocator()</code>.<br>
<b>Effects:</b> Does nothing if <code>nh</code> is empty; otherwise,
inserts the node owned by <code>nh</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<br>
<b>Postconditions:</b> <code>nh</code> is empty.<br>
<b>Returns:</b> A value <code>p</code> of type <code>insert_return_type</code>.
If <code>nh</code> is empty, <code>p.position</code> is <code>end()</code>,
<code>p.inserted</code> is <code>false</code> and <code>p.node</code> is empty;
on successful insertion, <code>p.position</code> points to the element inserted,
<code>p.inserted</code> is <code>true</code> and <code>p.node</code>
is empty;
if the insertion failed, <code>p.position</code> points to an element that caused
the insertion to be banned, <code>p.inserted</code> is <code>false</code> and
<code>p.node</code> owns the original node.
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. If an exception
is thrown, <code>nh</code> is not changed.<br>
</blockquote>
<code>node_type extract(const_iterator position);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.<br>
<b>Effects:</b> Extracts the node of the element pointed to by <code>position</code>.<br>
<b>Returns:</b> A node handle owning the extracted node.<br>
<b>Complexity:</b> <code>O(D(n))</code>.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<code>iterator erase(iterator position);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.</br>
of the index.<br>
<b>Effects:</b> Deletes the element pointed to by <code>position</code>.<br>
<b>Returns:</b> An iterator pointing to the element immediately following
the one that was deleted, or <code>end()</code>
@@ -545,11 +729,14 @@ 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&amp; x);</code></a>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.</br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
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
@@ -568,16 +755,19 @@ belongs remains in its original state.
<code>template&lt;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
<b>Requires:</b> <code>mod</code> is a unary function object
accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
iterator of the index.
The execution of <code>mod(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, does not invoke any operation of the
<code>multi_index_container</code> after <code>e</code> is directly modified
or, before modification, if the operation would invalidate <code>position</code>.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and rearranges <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
indices does not change the position of the element with respect to the index;
rearrangement on other indices may or might not suceed. If the rearrangement
rearrangement on other indices may or might not succeed. If the rearrangement
fails, the element is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the
operation succeeds.<br>
@@ -585,70 +775,166 @@ operation succeeds.<br>
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
user-provided operation (including <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
objects accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The execution of <code>mod(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, does not invoke any operation of the
<code>multi_index_container</code> after <code>e</code> is directly modified
or, before modification, if the operation would invalidate <code>position</code>.
<code>back(e)</code> does not invoke any operation of the
<code>multi_index_container</code>.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
indices does not change the position of the element with respect to the index;
rearrangement on other indices may or might not succeed.
If the rearrangement fails, <code>back(e)</code> is invoked: if the resulting value
of <code>e</code> is consistent with its original position and constraints in all
indices, the element is kept, otherwise it is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>mod</code> or <code>back</code> throw an
exception or <code>back(e)</code> fails to properly restore the element or there is
a throwing user-provided operation after invoking <code>back(e)</code>, in which cases
the modified element is erased. If <code>back</code>
throws inside the handling code executing after some other user-provided
operation has thrown, it is the exception generated by <code>back</code> that
is rethrown.
</blockquote>
<h4><a name="list_operations">List operations</a></h4>
<p>
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
Sequenced indices provide the full set of list operations found in
<code>std::list</code>, extended in some cases such as <code>splice</code>;
the semantics of these member functions, however,
typically differs from that of <code>std::list</code> as insertions
may 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>&amp; x);</code>
<a name="splice"><code>template&lt;typename Index&gt; void splice(const_iterator position,Index&amp;&amp; x);</code></a>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
<code>&amp;x!=this</code>.</br>
<b>Effects:</b> Inserts the contents of <code>x</code> before <code>position</code>,
in the same order as they were in <code>x</code>. Those elements succesfully
inserted are erased from <code>x</code>.<br>
<b>Complexity:</b> <code>O(x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
<b>Exception safety:</b> Basic.<br>
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
<a href="multi_index_container.html#node_type">node-compatible</a>
<code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index, and must be exactly <code>end()</code>
if the source and destination containers are the same.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>splice</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>,</span><span class=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>
</pre></blockquote>
</blockquote>
<code>void splice(iterator position,<b>index class name</b>&amp; x,iterator i);</code>
<code>
template&lt;typename Index&gt; std::pair&lt;iterator,bool&gt; splice(<br>
&nbsp;&nbsp;const_iterator position,Index&amp;&amp; x,<br>
&nbsp;&nbsp;typename std::remove_reference_t&lt;Index&gt;::const_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>&amp;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>&amp;x==this</code>, no iterator or reference
is invalidated.<br>
<b>Complexity:</b> If <code>&amp;x==this</code>, constant; otherwise
<code>O(I(n) + D(n))</code>.<br>
<b>Exception safety:</b> If <code>&amp;x==this</code>, <code>nothrow</code>;
otherwise, strong.<br>
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
<a href="multi_index_container.html#node_type">node-compatible</a>
<code>multi_index_container</code>.
If <code>get_allocator()!=x.get_allocator()</code>,
<code>value_type</code> must be <code>CopyInsertable</code> into the destination
<code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.
<code>i</code> is a valid dereferenceable iterator of <code>x</code>.<br>
<b>Effects:</b>
<ul>
<li><b>(Same container)</b> if the source and destination containers are the same, repositions
the element pointed to by <code>i</code> before <code>position</code> unless both
iterators refer to the same element.</li>
<li><b>(Transfer splice)</b> else, if <code>get_allocator()==x.get_allocator()</code>,
transfers the node of the element referred to by <code>i</code> into the
destination <code>multi_index_container</code> right before <code>position</code>
if insertion is allowed by all other indices of the <code>multi_index_container</code>.</li>
<li><b>(Destructive splice)</b> else, insertion of <code>*i</code> is tried before
<code>position</code>; if the operation is successful, the element is erased from <code>x</code>.
</li>
</ul>
<b>Postconditions:</b> If transfer succeeds, for any index in the source container
having the same <code>iterator</code>/<code>const_iterator</code> types as the corresponding
index in the destination container, iterators referring to <code>*i</code>
remain valid and behave as iterators of the destination index.<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 (either through transfer or copy insertion)
took place or the source and destination containers are the same.
If <code>p.second</code> is <code>true</code>,
<code>p.first</code> points to the inserted element or to <code>*i</code> if the
source and destination containers are the same; 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> If the source and destination containers are the same,
constant; otherwise, <code>O(I(n)+D(x.size()))</code>.<br>
<b>Exception safety:</b> If the source and destination containers are the same,
<code>nothrow</code>; otherwise strong.<br>
<b>Implementation note:</b> The destructive variant of this operation is provided
for reasons of backwards compatibility with previous versions of this library where
allocator equality was not required.
</blockquote>
<code>void splice(iterator position,<b>index class name&amp;</b> x,iterator first,iterator last);</code>
<code>
template&lt;typename Index&gt; void splice(<br>
&nbsp;&nbsp;const_iterator position,Index&amp;&amp; x,<br>
&nbsp;&nbsp;typename std::remove_reference_t&lt;Index&gt;::const_iterator first,<br>
&nbsp;&nbsp;typename std::remove_reference_t&lt;Index&gt;::const_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>&amp;x==this</code>, no copy or deletion is performed, and insertions are
always succesful.<br>
<b>Postconditions:</b> If <code>&amp;x==this</code>, no iterator or reference
is invalidated.<br>
<b>Complexity:</b> If <code>&amp;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>&amp;x==this</code>, <code>nothrow</code>;
otherwise, basic.<br>
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
<a href="multi_index_container.html#node_type">node-compatible</a>
<code>multi_index_container</code>.
If <code>get_allocator()!=x.get_allocator()</code>,
<code>value_type</code> must be <code>CopyInsertable</code> into the destination
<code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index and does not point to any element in
[<code>first</code>,<code>last</code>).
[<code>first</code>,<code>last</code>) is a valid range of <code>x</code>.<br>
<b>Effects:</b>
<ul>
<li><b>(Same container)</b> if the source and destination containers are the same, repositions all the elements
of [<code>first</code>,<code>last</code>), in this order, before <code>position</code>.
</li>
<li><b>(Transfer splice)</b> else, if <code>get_allocator()==x.get_allocator()</code>, then, for each node in
[<code>first</code>,<code>last</code>), in this order, the node is transferred to the
<code>multi_index_container</code> right before <code>position</code>
if insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
<li><b>(Destructive splice)</b> else, for each element in [<code>first</code>,<code>last</code>), in this order,
insertion is tried before <code>position</code>; if the operation is successful, the
element is erased from <code>x</code>.
</li>
</ul>
<b>Postconditions:</b> For any index in the source container having the same
<code>iterator</code>/<code>const_iterator</code> types as the corresponding
index in the destination container, iterators referring to the transferred elements
remain valid and behave as iterators of the destination index.<br>
<b>Complexity:</b> If <code>&amp;x==this</code>, constant; else, if
the source and destination containers are the same, <code>O(m)</code>;
otherwise, <code>O(m*(I(n+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 the source and destination containers are the same,
<code>nothrow</code>; otherwise basic.<br>
<b>Implementation note:</b> The destructive variant of this operation is provided
for reasons of backwards compatibility with previous versions of this library where
allocator equality was not required.
</blockquote>
<code>void remove(const value_type&amp; value);</code>
@@ -665,7 +951,7 @@ is the number of elements erased.<br>
<blockquote>
<b>Effects:</b> Erases all elements <code>x</code> of the index for which
<code>pred(x)</code> holds..<br>
<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.
@@ -697,44 +983,45 @@ is the number of elements erased.<br>
<code>void merge(index class name&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>std::less&lt;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>.
<b>Requires:</b>
Either <code>get_allocator()==x.get_allocator()</code> or <code>value_type</code>
is <code>CopyInsertable</code> into the <code>multi_index_container</code>.
<code>std::less&lt;value_type&gt;</code> induces a
strict weak ordering over <code>value_type</code>.
Both the index and <code>x</code> are sorted according to
<code>std::less&lt;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
<code>std::less&lt;value_type&gt;</code>.<br>
<b>Effects:</b> Attempts to splice every element of <code>x</code> into the
corresponding position of the index (according to the order). The resulting sequence
is stable, i.e. equivalent elements of either container preserve their
relative position. In the special case <code>&amp;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>
Validity of iterators and references is preserved, except to elements removed
from <code>x</code> if <code>get_allocator()!=x.get_allocator()</code>.<br>
<b>Complexity:</b> If <code>&amp;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>&amp;x==this</code>, <code>nothrow</code>;
otherwise, basic.<br>
</blockquote>
<code>template &lt;typename Compare> void merge(index class name&amp; x,Compare comp);</code>
<code>template &lt;typename Compare&gt; void merge(index class name&amp; x,Compare comp);</code>
<blockquote>
<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>.
<b>Requires:</b>
Either <code>get_allocator()==x.get_allocator()</code> or <code>value_type</code>
is <code>CopyInsertable</code> into the <code>multi_index_container</code>.
<code>Compare</code> induces a strict weak ordering 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
<b>Effects:</b> Attempts to splice every element of <code>x</code> into the
corresponding position of the index (according to <code>comp</code>). The resulting
sequence is stable, i.e. equivalent elements of either container preserve
their relative position. In the special case <code>&amp;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>
Validity of iterators and references is preserved, except to elements removed
from <code>x</code> if <code>get_allocator()!=x.get_allocator()</code>.<br>
<b>Complexity:</b> If <code>&amp;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>&amp;x==this</code>, <code>nothrow</code>;
@@ -744,24 +1031,22 @@ otherwise, basic.<br>
<code>void sort();</code>
<blockquote>
<b>Requires:</b> <code>std::less&lt;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>Requires:</b> <code>std::less&lt;value_type&gt;</code> induces a
strict weark ordering over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to
<code>std::less&lt;value_type></code>. The sorting is stable, i.e.
<code>std::less&lt;value_type&gt;</code>. The sorting is stable, i.e.
equivalent elements preserve their relative position.<br>
<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&lt;value_type></code> does not throw; otherwise, basic.
<code>std::less&lt;value_type&gt;</code> does not throw; otherwise, basic.
</blockquote>
<code>template &lt;typename Compare> void sort(Compare comp);</code>
<code>template &lt;typename Compare&gt; 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>Requires:</b> <code>Compare</code> induces a
strict weak ordering 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>
@@ -770,23 +1055,21 @@ is stable, i.e. equivalent elements preserve their relative position.<br>
not throw; otherwise, basic.
</blockquote>
<code>void reverse();</code>
<code>void reverse()noexcept;</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>
<h4><a name="rearrange_operations">Rearrange 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.
These operations, without counterpart in <code>std::list</code>
(although <code>splice</code> provides partially overlapping
functionality), perform individual and global repositioning of elements
inside the index.
</p>
<code>void relocate(iterator position,iterator i);</code>
@@ -816,6 +1099,20 @@ is repositioned just before <code>position</code>.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<a name="rearrange"><code>template&lt;typename InputIterator> void rearrange(InputIterator first);</code></a>
<blockquote>
<b>Requires:</b> The range [<code>first</code>,
<code>std::advance(first,n)</code>),
where <code>n</code> is the size of the index, is a
<a href="indices.html#views">free view</a> of the index.<br>
<b>Effects:</b> The elements are rearranged so as to match the
order of the previously described view.<br>
<b>Postconditions:</b> No iterator or reference is invalidated.<br>
<b>Complexity:</b> <code>O(n)</code>.<br>
<b>Exception safety:</b> Basic.<br>
</blockquote>
<h4><a name="serialization">Serialization</a></h4>
<p>
@@ -839,7 +1136,7 @@ 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
<b>Postconditions:</b> On successful loading, each of the elements of
[<code>begin()</code>, <code>end()</code>) is a restored copy of the corresponding
element in [<code>m.get&lt;i&gt;().begin()</code>, <code>m.get&lt;i&gt;().end()</code>),
where <code>i</code> is the position of the sequenced index in the container.
@@ -857,11 +1154,11 @@ 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
<b>Postconditions:</b> On successful 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.
and the restored <code>it'</code> an <code>iterator</code>, or vice versa.
</blockquote>
<hr>
@@ -872,15 +1169,15 @@ Hashed indices
<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
<div class="next_link"><a href="rnd_indices.html"><img src="../next.gif" alt="random access indices" border="0"><br>
Random access indices
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised February 7th 2005</p>
<p>Revised August 30th 2021</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2021 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+800 -7
View File
@@ -5,6 +5,10 @@
<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">
<link rel="start" href="index.html">
<link rel="prev" href="future_work.html">
<link rel="up" href="index.html">
<link rel="next" href="acknowledgements.html">
</head>
<body>
@@ -23,21 +27,811 @@ Acknowledgements
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#boost_1_92">Boost 1.92 release</a></li>
<li><a href="#boost_1_91">Boost 1.91 release</a></li>
<li><a href="#boost_1_85">Boost 1.85 release</a></li>
<li><a href="#boost_1_84">Boost 1.84 release</a></li>
<li><a href="#boost_1_83">Boost 1.83 release</a></li>
<li><a href="#boost_1_82">Boost 1.82 release</a></li>
<li><a href="#boost_1_81">Boost 1.81 release</a></li>
<li><a href="#boost_1_80">Boost 1.80 release</a></li>
<li><a href="#boost_1_79">Boost 1.79 release</a></li>
<li><a href="#boost_1_78">Boost 1.78 release</a></li>
<li><a href="#boost_1_77">Boost 1.77 release</a></li>
<li><a href="#boost_1_74">Boost 1.74 release</a></li>
<li><a href="#boost_1_73">Boost 1.73 release</a></li>
<li><a href="#boost_1_71">Boost 1.71 release</a></li>
<li><a href="#boost_1_70">Boost 1.70 release</a></li>
<li><a href="#boost_1_69">Boost 1.69 release</a></li>
<li><a href="#boost_1_68">Boost 1.68 release</a></li>
<li><a href="#boost_1_67">Boost 1.67 release</a></li>
<li><a href="#boost_1_66">Boost 1.66 release</a></li>
<li><a href="#boost_1_64">Boost 1.64 release</a></li>
<li><a href="#boost_1_62">Boost 1.62 release</a></li>
<li><a href="#boost_1_60">Boost 1.60 release</a></li>
<li><a href="#boost_1_59">Boost 1.59 release</a></li>
<li><a href="#boost_1_58">Boost 1.58 release</a></li>
<li><a href="#boost_1_57">Boost 1.57 release</a></li>
<li><a href="#boost_1_56">Boost 1.56 release</a></li>
<li><a href="#boost_1_55">Boost 1.55 release</a></li>
<li><a href="#boost_1_54">Boost 1.54 release</a></li>
<li><a href="#boost_1_49">Boost 1.49 release</a></li>
<li><a href="#boost_1_48">Boost 1.48 release</a></li>
<li><a href="#boost_1_47">Boost 1.47 release</a></li>
<li><a href="#boost_1_44">Boost 1.44 release</a></li>
<li><a href="#boost_1_43">Boost 1.43 release</a></li>
<li><a href="#boost_1_42">Boost 1.42 release</a></li>
<li><a href="#boost_1_41">Boost 1.41 release</a></li>
<li><a href="#boost_1_38">Boost 1.38 release</a></li>
<li><a href="#boost_1_37">Boost 1.37 release</a></li>
<li><a href="#boost_1_36">Boost 1.36 release</a></li>
<li><a href="#boost_1_35">Boost 1.35 release</a></li>
<li><a href="#boost_1_34">Boost 1.34 release</a></li>
<li><a href="#boost_1_33_1">Boost 1.33.1 release</a></li>
<li><a href="#boost_1_33">Boost 1.33 release</a></li>
</ul>
<h2><a name="boost_1_92">Boost 1.92 release</a></h2>
<p>
<ul>
<li>Fancy pointer support has been extended so that <code>multi_index_container</code>
iterators now store references to the elements through the allocator's pointer type.
In particular, this means that iterators can now be placed in shared memory using
<a href="../../interprocess/index.html">Boost.Interprocess</a> allocators.
</li>
<li>Fixed a performance issue with hashed indices when rehashing at very large
container sizes (<a href="https://github.com/boostorg/multi_index/pull/94">PR#94</a>).
Contributed by Daniel Kr&aacute;l.
</li>
</ul>
</p>
<h2><a name="boost_1_91">Boost 1.91 release</a></h2>
<p>
<ul>
<li><b>Breaking change:</b> All type lists accepted or provided by the library (<code>indexed_by</code>,
<code>tag</code>, nested typedefs <code>index_specifier_type_list</code>,
<code>index_type_list</code>, <code>iterator_type_list</code> and
<code>const_iterator_type_list</code>) are no longer based on
<a href="../../mpl">Boost.MPL</a> but instead they are now
<a href="../../mp11/doc/html/mp11.html#definitions">Boost.Mp11 lists</a>.
As a result, Boost.MultiIndex doesn't depend anymore on Boost.MPL.
It is expected that most user code won't be impacted by this
change, but the previous behavior may be restored, however, by
globally defining the macro
<code>BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT</code>.
Legacy support for Boost.MPL may be eventually deprecated and removed in the future.
</li>
<li><b>Breaking change:</b> <code>composite_key</code> and associated
class templates (<code>composite_key_equal_to</code>, <code>composite_key_compare</code>,
<code>composite_key_hash</code>) have been made variadic (previously the maximum
number of template arguments was limited by <code>BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE</code>).
This change should be transparent to users, with the exception that
<code>composite_key::key_extractors</code> returns a <code>std::tuple</code>
instead of a <code>boost::tuple</code> (and similarly for the rest of affected
class templates).
</li>
<li>Removed internal workarounds and fallbacks to support pre-C++11 compilers.
</li>
</ul>
</p>
<h2><a name="boost_1_85">Boost 1.85 release</a></h2>
<p>
<ul>
<li>Fixed documentation errors.</li>
</ul>
</p>
<h2><a name="boost_1_84">Boost 1.84 release</a></h2>
<p>
<ul>
<li>Fixed a serialization-related compile-time bug in old compilers
without ADL support
(<a href="https://github.com/boostorg/multi_index/issues/70">issue #70</a>).
</li>
</ul>
</p>
<h2><a name="boost_1_83">Boost 1.83 release</a></h2>
<p>
<ul>
<li>Updated range <code>insert</code> in non-unique ordered indices to preserve insertion order
of equivalent elements
(<a href="https://github.com/boostorg/multi_index/issues/68">issue #68</a>).
</li>
<li>Serialization now uses <code>std::size_t</code> instead of <code>unsigned long</code>
to save and load the size of a <code>multi_index_container</code>
(<code>unsigned long</code> is smaller than <code>std::size_t</code> in LLP64 data models).
<code>multi_index_container</code> serialization
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
bumped from 3 to 4 to reflect this change.
</li>
</ul>
</p>
<h2><a name="boost_1_82">Boost 1.82 release</a></h2>
<p>
<ul>
<li>Serialization now uses <code>unsigned long</code> instead of
<a href="../../serialization/doc/wrappers.html#collection_size_type"><code>collection_size_type</code></a>,
and <code>multi_index_container</code> serialization
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
bumped from 2 to 3 to reflect this change.
Reading old archives may fail for custom archive types giving special treatment to
<code>collection_size_type</code> values: if this is the case, globally define
the macro <code>BOOST_MULTI_INDEX_ENABLE_SERIALIZATION_COMPATIBILITY_V2</code>
to ensure backwards compatibility in reading operations.
</li>
<li>Maintenance work.</li>
</ul>
</p>
<h2><a name="boost_1_81">Boost 1.81 release</a></h2>
<p>
<ul>
<li>Maintenance work.</li>
</ul>
</p>
<h2><a name="boost_1_80">Boost 1.80 release</a></h2>
<p>
<ul>
<li>Maintenance work.</li>
</ul>
</p>
<h2><a name="boost_1_79">Boost 1.79 release</a></h2>
<p>
<ul>
<li>Improved the efficiency of <code>count</code> operations in ranked indices from
<code>O(log(n) + count)</code> to <code>O(log(n))</code>.
Contributed by Damian Sawicki.
</li>
<li>Maintenance work.</li>
</ul>
</p>
<h2><a name="boost_1_78">Boost 1.78 release</a></h2>
<p>
<ul>
<li>Added <code>contains</code> to key-based indices
(<a href="https://github.com/boostorg/multi_index/issues/35">issue #35</a>).
</li>
<li>Added <code>merge</code> operations to key-based indices. The functionality goes beyond
the standard specification for (unordered) associative containers in a number of ways,
most notably:
<ul>
<li>The source index can be of any type, including non key-based indices.</li>
<li>Partial merge is provided: for instance, <code>x.merge(y,first,last)</code>
merges only the elements of <code>y</code> within [<code>first</code>,<code>last</code>).
</li>
</ul>
</li>
<li>Previous versions of <code>splice</code> for sequenced and random access indices
were destructive, i.e. elements were copy-inserted into the destination and then erased
from the source. Now, <code>splice</code> is based on node transfer much as <code>merge</code>
in key-based indices, and has been similarly extended to accept source indices of any type:
in fact, <code>splice</code> can be regarded as a frontend to the same functionality
provided by <code>merge</code> in key-based indices. For reasons of backwards compatibility,
the destructive behavior of <code>splice</code> has been retained in the case that the
source and destination containers have unequal allocators.
</li>
<li>The fact has been documented that index iterator types do only depend on <code>node_type</code>
and the position of the index in its <code>multi_index_container</code>,
(except for hashed indices, where uniqueness/non-uniqueness is also a dependency). This has
implications on the validity of iterators to elements transferred by <code>merge</code> or
<code>splice</code>. This property is a variant of what has been called
<a href="https://wg21.link/n2980">SCARY iterators</a> in the C++ standard mailing lists.
SCARYness is currently (August 2021) not mandated for standard containers.
</li>
<li>Iterator SCARYness is now also preserved in <a href="tutorial/debug.html#safe_mode">safe mode</a>.
</li>
</ul>
</p>
<h2><a name="boost_1_77">Boost 1.77 release</a></h2>
<p>
<ul>
<li>Maintenance work.</li>
</ul>
</p>
<h2><a name="boost_1_74">Boost 1.74 release</a></h2>
<p>
<ul>
<li>
Added <a href="tutorial/indices.html#node_handling">node extraction and insertion</a>
following the analogous interface of associative containers as introduced in C++17.
This feature has also been extended to non key-based indices, in contrast to C++
standard library sequence containers, which do not provide such functionality.
</li>
<li>Clarified documentation on read/write key extractors
(<a href="https://github.com/boostorg/multi_index/issues/32">issue #32</a>).
</li>
<li>Maintenance work.</li>
</ul>
</p>
<h2><a name="boost_1_73">Boost 1.73 release</a></h2>
<p>
<ul>
<li><code>multi_index_container</code> is now
<a href="https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer"><code>AllocatorAware</code></a>.
</li>
<li>Swapping of internal <code>KeyFromValue</code>, <code>Compare</code>, <code>Hash</code>
and <code>Pred</code> objects now selects the appropriate <code>swap</code>
function between <code>std::swap</code> and ADL candidates,
in accordance with standard specifications in <b>[swappable.requirements]</b>
(<a href="https://github.com/boostorg/multi_index/issues/29">issue #29</a>).
</li>
<li>Provided some internal copy constructors and assignment operators whose default
implicit definition is deprecated in C++11 onwards (<b>[depr.impldec]</b>), which
was warned about on some compilers.
</li>
<li>Maintenance work.</li>
</ul>
</p>
<h2><a name="boost_1_71">Boost 1.71 release</a></h2>
<p>
<ul>
<li>Added <a href="tutorial/key_extraction.html#x_mem_fun">variants of
<code>const_mem_fun</code> and <code>mem_fun</code></a> for
differently qualified member functions
(<a href="https://github.com/boostorg/multi_index/issues/24">issue #24</a>).
</li>
<li>Terse <a href="reference/key_extraction.html#key">key</a> specification syntax
now correctly handles <code>noexcept</code>-specified member functions
(<a href="https://github.com/boostorg/multi_index/issues/24">issue #24</a>).
</li>
</ul>
</p>
<h2><a name="boost_1_70">Boost 1.70 release</a></h2>
<p>
<ul>
<li><code>size_type</code> and <code>difference_type</code> are now
defined as the allocator's same-named types. This will not make any
difference in the vast majority of cases, but allows for some degree
of control of resulting internal structures via user-defined allocator
types (see
<a href="https://github.com/boostorg/multi_index/issues/17">issue #17</a>
for motivation). For the moment being, this change is <i>not</i>
documented in the reference section (i.e., it has semi-official status).
</li>
<li>Maintenance work.</li>
</ul>
</p>
<h2><a name="boost_1_69">Boost 1.69 release</a></h2>
<p>
<ul>
<li>Introduced an alternative
<a href="tutorial/key_extraction.html#key">terse key specification syntax</a>
for C++17 compliant environments.
</li>
</ul>
</p>
<h2><a name="boost_1_68">Boost 1.68 release</a></h2>
<p>
<ul>
<li>Containers of moveable but non-copyable elements can now be serialized
(ticket <a href="https://svn.boost.org/trac10/ticket/13478">#13478</a>).
Thanks to S&eacute;bastien Paris for the report.
</li>
<li><code>multi_index_container</code>'s default constructor is no longer
<code>explicit</code>
(ticket <a href="https://svn.boost.org/trac10/ticket/13518">#13518</a>).
</li>
</ul>
</p>
<h2><a name="boost_1_67">Boost 1.67 release</a></h2>
<p>
<ul>
<li>Elements with overloaded <code>operator&amp;</code> are now fully accepted
(ticket <a href="https://svn.boost.org/trac10/ticket/13307">#13307</a>).
Thanks to Daniel Frey for his updating
<a href="../../utility/operators.htm#deref">Boost.Operators</a> to help
fix this issue.
</li>
<li>Avoided usage of <code>std::allocator</code> members deprecated in C++17.
Contributed by Daniela Engert.
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_66">Boost 1.66 release</a></h2>
<p>
<ul>
<li>Made <code>modify</code> and <code>modify_key</code> more robust so that
the modified element is erased if the modifier throws or the rollback
functor does not properly restore the element (full discussion at
ticket <a href="https://svn.boost.org/trac/boost/ticket/12542">#12542</a>).
This is technically backwards incompatible; for instance, the following code:
<blockquote><pre>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>modify</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=keyword>auto</span><span class=special>&amp;){</span><span class=keyword>throw</span> <span class=number>0</span><span class=special>;});</span>
</pre></blockquote>
keeps the container <code>c</code> untouched in former versions of Boost whereas
now <code>c.begin()</code> is erased. Thanks to Jon Kalb for raising the issue.
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_64">Boost 1.64 release</a></h2>
<p>
<ul>
<li>Fixed a bug related to ambiguous references in the presence of more than
one ranked index
(ticket <a href="https://svn.boost.org/trac/boost/ticket/12955">#12955</a>).
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_62">Boost 1.62 release</a></h2>
<p>
<ul>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_60">Boost 1.60 release</a></h2>
<p>
<ul>
<li>Fixed an interoperability problem with <a href="http://www.qt.io/">Qt</a> due to the
optional definition of a macro with name <code>foreach</code> in this framework.</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_59">Boost 1.59 release</a></h2>
<p>
<ul>
<li>Added <a href="tutorial/indices.html#rnk_indices">ranked indices</a>.</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_58">Boost 1.58 release</a></h2>
<p>
<ul>
<li>The efficiency of lookup operations has improved in situations where they involve
the generation of temporary values of <code>key_type</code>. Consider for instance
the following code:
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>multi_t</span><span class=special>;</span>
<span class=special>...</span>
<span class=identifier>multi_t</span> <span class=identifier>m</span><span class=special>=...;</span>
<span class=identifier>m</span><span class=special>.</span><span class=identifier>find</span><span class=special>(</span><span class=string>&quot;boost&quot;</span><span class=special>);</span> <span class=comment>// passed a const char*, not a std::string</span>
</pre></blockquote>
In previous versions of the library, the <code>find</code> operation generates
several temporary <code>std::string</code>s (one every time an internal comparison is made).
In sufficiently advanced compilers, this is now avoided so that only one temporary is
created.
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_57">Boost 1.57 release</a></h2>
<p>
<ul>
<li>When <code>std::tuple</code>s are available, these can be used for lookup operations
in indices equipped with composite keys. <code>boost::tuple</code>s are also supported
for backwards compatibility.
</li>
</ul>
</p>
<h2><a name="boost_1_56">Boost 1.56 release</a></h2>
<p>
<ul>
<li>The <code>erase(iterator)</code> member function of hashed indices
used to have poor performance under low load conditions due to the requirement
that an iterator to the next element must be returned (see ticket
<a href="https://svn.boost.org/trac/boost/ticket/4264">#4264</a>). In accordance with
the resolution of <a href="http://lwg.github.io/issues/lwg-closed.html#579">LWG
issue #579</a>, this problem has been fixed while maintaining the interface of
<code>erase</code>, at the expense of using one more
word of memory per element. In fact, C++ complexity requirements on unordered
associative containers have been improved for hashed indices so that
<ul>
<li>deletion of a given element is unconditionally constant-time,</li>
<li>worst-case performance is not <code>O(n)</code> but <code>O(n<sub>dist</sub>)</code>,
where <code>n<sub>dist</sub></code> is the number of non-equivalent elements in the index.
</li>
</ul>
Due to the fact that hashed indices rely on a new data structure, the internal representation of
their iterators and local iterators have changed, which affects serialization: their corresponding
serialization <a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
bumped from 0 to 1. Old archives involving hashed index (local) iterators can be loaded
by Boost 1.56 version of Boost.MultiIndex, but not the other way around.
</li>
<li>Hashed indices now provide <code>reserve</code>.</li>
<li>Hashed indices can now be checked for equality and inequality following the
(suitably adapted) C++ standard specification in <b>[unord.req]</b>.</li>
<li>The public interface of Boost.MultiIndex provide <code>noexcept</code> specifications
where appropriate (for compliant compilers).
</li>
<li>Improved performance of failed insertions into a <code>multi_index_container</code>.</li>
<li>Much internal code aimed at supporting MSVC++ 7.0 and prior has been removed.
Compilation times without this legacy code might be slightly faster.
</li>
<li>Fixed a bug with insertion via iterators dereferencing to rvalues
(ticket <a href="https://svn.boost.org/trac/boost/ticket/9665">#9665</a>).
</li>
<li>Made Boost.MultiIndex compatible with <code>BOOST_BIND_NO_PLACEHOLDERS</code>
(ticket <a href="https://svn.boost.org/trac/boost/ticket/9798">#9798</a>).
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_55">Boost 1.55 release</a></h2>
<p>
<ul>
<li>Boost.MultiIndex has been brought to a higher level of compliance
with C++11.
<ul>
<li><code>multi_index_container</code> is now efficiently movable.</li>
<li>Initializer lists supported.</li>
<li>Emplace functions provided.</li>
<li>Non-copyable elements (such as <code>std::unique_ptr&lt;T&gt;</code>) supported. This includes
insertion of a range [<code>first</code>,<code>last</code>) where the iterators point to a type that is
convertible to that of the element: no copy construction happens in the process.
</li>
<li>Random access indices provide <code>shrink_to_fit()</code>.</li>
</ul>
Refer to the compiler specifics section for limitations
on pre-C++11 compilers.
</li>
<li>The following classes are deprecated:
<ul>
<li><a href="reference/key_extraction.html#member_offset"><code>member_offset</code></a>,</li>
<li><a href="reference/key_extraction.html#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>,</li>
<li><a href="reference/key_extraction.html#const_mem_fun_explicit"><code>mem_fun_explicit</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_equal_to"><code>composite_key_result_equal_to</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_less"><code>composite_key_result_less</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_greater"><code>composite_key_result_greater</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_hash"><code>composite_key_result_hash</code></a>.</li>
</ul>
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_54">Boost 1.54 release</a></h2>
<p>
<ul>
<li>Suppressed some potential warnings described in
tickets <a href="https://svn.boost.org/trac/boost/ticket/8034">#8034</a> and <a href="https://svn.boost.org/trac/boost/ticket/8129">#8129</a>.
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_49">Boost 1.49 release</a></h2>
<p>
<ul>
<li>Suppressed a potential narrow conversion warning described in
ticket <a href="https://svn.boost.org/trac/boost/ticket/3365">#3365</a>.
</li>
</ul>
</p>
<h2><a name="boost_1_48">Boost 1.48 release</a></h2>
<p>
<ul>
<li>Fixed a compatibility problem with
<a href="../../../doc/html/foreach.html">Boost.Foreach</a>
(ticket <a href="https://svn.boost.org/trac/boost/ticket/5741">#5741</a>).
</li>
</ul>
</p>
<h2><a name="boost_1_47">Boost 1.47 release</a></h2>
<p>
<ul>
<li>Fixed an ADL problem in
<a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>
related with <a href="../../../doc/html/ref.html">Boost.Ref</a>.
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_44">Boost 1.44 release</a></h2>
<p>
<ul>
<li>
Fixed a bug preventing the use of <code>modify_key</code> with
rollback in <a href="reference/ord_indices.html#modify_key">ordered</a> and
<a href="reference/hash_indices.html#modify_key">hashed</a> indices when
<code>Modifier</code> and <code>Rollback</code> are different types
(ticket <a href="https://svn.boost.org/trac/boost/ticket/4130">#4130</a>).
</li>
</ul>
</p>
<h2><a name="boost_1_43">Boost 1.43 release</a></h2>
<p>
<ul>
<li>
<a href="../../serialization/doc/serialization.html#constructors">Serialization
of non default constructible values</a> is now properly supported
through user-provided facilities <code>save_construct_data</code> and
<code>load_construct_data</code>.
<code>multi_index_container</code> serialization
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
bumped from 1 to 2.
</li>
</ul>
</p>
<h2><a name="boost_1_42">Boost 1.42 release</a></h2>
<p>
<ul>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_41">Boost 1.41 release</a></h2>
<p>
<ul>
<li>Serialization now uses the portable
<a href="../../serialization/doc/wrappers.html#collection_size_type"><code>collection_size_type</code></a>
type instead of the original <code>std::size_t</code> (ticket
<a href="https://svn.boost.org/trac/boost/ticket/3365">#3365</a>).
<code>multi_index_container</code> serialization
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
bumped from 0 to 1.
</li>
<li>Fixed a concurrency bug in the implementation of
<a href="tutorial/debug.html#safe_mode">safe mode</a>
(ticket <a href="https://svn.boost.org/trac/boost/ticket/3462">#3462</a>).
</li>
</ul>
</p>
<h2><a name="boost_1_38">Boost 1.38 release</a></h2>
<p>
<ul>
<li>These constructs are deprecated:
<ul>
<li><code>nth_index_iterator&lt;MultiIndexContainer,N&gt;::type</code>,</li>
<li><code>multi_index_container&lt;...&gt;::nth_index_iterator&lt;N&gt;::type</code>,</li>
<li><code>nth_index_const_iterator&lt;MultiIndexContainer,N&gt;::type</code>,</li>
<li><code>multi_index_container&lt;...&gt;::nth_index_const_iterator&lt;N&gt;::type</code>,</li>
<li><code>index_iterator&lt;MultiIndexContainer,Tag&gt;::type</code>,</li>
<li><code>multi_index_container&lt;...&gt;::index_iterator&lt;Tag&gt;::type</code>,</li>
<li><code>index_const_iterator&lt;MultiIndexContainer,Tag&gt;::type</code>,</li>
<li><code>multi_index_container&lt;...&gt;::index_const_iterator&lt;Tag&gt;::type</code>.</li>
</ul>
Use the following instead:
<ul>
<li><code>nth_index&lt;MultiIndexContainer,N&gt;::type::iterator</code>,</li>
<li><code>multi_index_container&lt;...&gt;::nth_index&lt;N&gt;::type::iterator</code>,</li>
<li><code>nth_index&lt;MultiIndexContainer,N&gt;::type::const_iterator</code>,</li>
<li><code>multi_index_container&lt;...&gt;::nth_index&lt;N&gt;::type::const_iterator</code>,</li>
<li><code>index&lt;MultiIndexContainer,Tag&gt;::type::iterator</code>,</li>
<li><code>multi_index_container&lt;...&gt;::index&lt;Tag&gt;::type::iterator</code>,</li>
<li><code>index&lt;MultiIndexContainer,Tag&gt;::type::const_iterator</code>,</li>
<li><code>multi_index_container&lt;...&gt;::index&lt;Tag&gt;::type::const_iterator</code>.</li>
</ul>
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_37">Boost 1.37 release</a></h2>
<p>
<ul>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_36">Boost 1.36 release</a></h2>
<p>
<ul>
<li><a name="stable_update">On prior versions of the library, the <a href="tutorial/indices.html#hash_updating">update
member functions</a> of hashed indices could alter the position of an element even if the
associated key did not change with the update. This is legal but probably unexpected behavior.
The functions have been rewritten to provide the additional guarantee that elements with
unmodified key will not change position in hashed indices, just as always was the case with
ordered indices. These guarantees are now documented in the reference.</a></li>
<li>Added the constructor <code>multi_index_container::multi_index_container(const allocator_type&amp;)</code>
to mimic the equivalent interface in STL sequence containers.
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_35">Boost 1.35 release</a></h2>
<p>
<ul>
<li>New <a href="tutorial/key_extraction.html#global_fun"><code>global_fun</code></a>
predefined key extractor.
</li>
<li>Added <a href="tutorial/indices.html#iterator_to"><code>iterator_to</code></a>
facility.
</li>
<li>Included <a href="tutorial/creation.html#special_allocator">support for
non-standard allocators</a> such as those of
<a href="../../interprocess/index.html">Boost.Interprocess</a>, which makes
<code>multi_index_container</code>s placeable in shared memory.
</li>
<li>New versions of <code>modify</code> and <code>modify_key</code> with
rollback, as described in the
<a href="tutorial/basics.html#ord_updating">tutorial</a>.
</li>
<li>Indices provide the new <code>cbegin</code>, <code>cend</code> and,
when applicable, <code>crbegin</code> and <code>crend</code>
member functions, in accordance with the latest drafts of the next
revision of the C++ standard.
</li>
<li>Hinted insertion in ordered indices fully conforms to the resolutions of
C++ Standard Library
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233">Defect
Report 233</a>. The new requirement that the point of insertion
be always as close as possible to the hint induces a different behavior than
exhibited in former releases of Boost.MultiIndex, which can potentially cause
backwards compatibility problems; in any case, the likelihood of these
compatibility issues arising in a real scenario is very low.
</li>
<li>Sequenced and random access indices now follow the requirements of the
C++ standard for sequence containers with respect to the operations
<code>assign(f,l)</code> and <code>insert(p,f,l)</code> (23.1.1/9): if
<code>f</code> and <code>l</code> are of the same integral type, the
iterator-based overloads of these member functions are avoided:
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span><span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>sequenced_container</span><span class=special>;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=identifier>l</span><span class=special>(...);</span>
<span class=identifier>sequenced_container</span> <span class=identifier>c</span><span class=special>;</span>
<span class=comment>// iterator-based overload of assign</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=identifier>l</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>l</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
<span class=comment>// The following is equivalent to
// c.assign(
// static_cast&lt;sequenced_container::size_type&gt;(10),100);
// that is, &quot;10&quot; and &quot;100&quot; are not taken to be iterators as
// in the previous expression.</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=number>10</span><span class=special>,</span><span class=number>100</span><span class=special>);</span>
</pre></blockquote>
</li>
<li>The performance of ordered indices <code>range</code> and
<code>equal_range</code> has been improved.
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_34">Boost 1.34 release</a></h2>
<p>
<ul>
<li>Added <a href="tutorial/indices.html#rnd_indices">random access
indices</a>.
</li>
<li>Non key-based indices provide new
<a href="tutorial/indices.html#rearrange">rearrange facilities</a>
allowing for interaction with external mutating algorithms.
</li>
<li>All predefined Boost.MultiIndex key extractors
instantiated for a given type <code>T</code> can handle objects of types
derived from or convertible to <code>T</code> (and
<a href="reference/key_extraction.html#chained_pointers">chained pointers</a>
to those). Previously, only objects of the exact type specified (along with
<code>reference_wrapper</code>s and chained pointers to them) were accepted.
</li>
<li><a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>
and related classes accept operands not included in tuples as if they were passed
in a tuple of length 1; this allows the user to omit tuple enclosing in
lookup operations involving composite keys when only the first key is provided.
</li>
<li>The core algorithms of ordered indices have been optimized, yielding
an estimated reduction of about 5% in insertion times.
</li>
<li>Size of ordered indices node headers have been reduced by 25% on
most platforms, using a well known
<a href="tutorial/indices.html#ordered_node_compression">optimization
technique</a>.
</li>
<li>The tutorial has been restructured, new examples added.</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<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="tutorial/debug.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>,
<li>Added <a href="tutorial/indices.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>Added <a href="advanced_topics.html#serialization">serialization support</a>
</li>
<li>Added <a href="tutorial/creation.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>
@@ -48,8 +842,7 @@ Acknowledgements
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.
reduction of symbol name lengths has been added.
</li>
<li>Restructured some parts of the documentation, new examples.</li>
<li>Maintenance fixes.</li>
@@ -70,9 +863,9 @@ Acknowledgements
<br>
<p>Revised March 3rd 2005</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2026 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+1 -1
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2004 Joaqu M Lez Muz.
/* 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)
+48 -26
View File
@@ -5,6 +5,10 @@
<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">
<link rel="start" href="index.html">
<link rel="prev" href="examples.html">
<link rel="up" href="index.html">
<link rel="next" href="future_work.html">
</head>
<body>
@@ -39,47 +43,57 @@ with some of the least common features offered by Boost.MultiIndex.
<th>Description</th>
</tr>
<tr>
<td><a href="../test/test_alloc_awareness.cpp"><code>test_alloc_awareness.cpp</code></a></td>
<td>Checks <a href="https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer">allocator
awareness</a>.</td>
</tr>
<tr class="odd_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_capacity.cpp"><code>test_capacity.cpp</code></a></td>
<td><code>empty</code>, <code>size</code>, <code>resize</code>
(non-key-based indices) and <code>reserve</code>/<code>capacity</code>
(random access indices only).</td>
</tr>
<tr class="odd_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">
<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>
<tr class="odd_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">
<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> .
(non key-based indices only) <code>assign</code>.
</tr>
<tr>
<tr class="odd_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">
<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 class="odd_tr">
<td><a href="../test/test_key.cpp"><code>test_key.cpp</code></a></td>
<td>Terse key specification syntax.</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>
<td>List-like operations particular to sequenced and random access indices.</td>
</tr>
<tr>
<td><a href="../test/test_modifiers.cpp"><code>test_modifiers.cpp</code></a></td>
@@ -87,37 +101,46 @@ with some of the least common features offered by Boost.MultiIndex.
</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>
<td>Boost.MPL interoperability (when <code> BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT</code> is enabled).</td>
</tr>
<tr>
<td><a href="../test/test_node_handling.cpp"><code>test_node_handling.cpp</code></a></td>
<td>Operations involving node extraction and insertion.</td>
</tr>
<tr class="odd_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">
<tr>
<td><a href="../test/test_projection.cpp"><code>test_projection.cpp</code></a></td>
<td>Projection of iterators among indices.</td>
</tr>
<tr>
<tr class="odd_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>
<td><a href="../test/test_rank_ops.cpp"><code>test_rank_ops.cpp</code></a></td>
<td>Specific operations of ranked indices.</td>
</tr>
<tr class="odd_tr">
<td><a href="../test/test_rearrange.cpp"><code>test_rearrange.cpp</code></a></td>
<td>Rearrange functions of sequenced and random access indices.</td>
</tr>
<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>
<tr class="odd_tr">
<td><a href="../test/test_serialization1.cpp"><code>test_serialization1.cpp</code></a><br>
<a href="../test/test_serialization2.cpp"><code>test_serialization2.cpp</code></a><br>
<a href="../test/test_serialization3.cpp"><code>test_serialization3.cpp</code></a></td>
<td>Serialization support.</td>
</tr>
<tr class="odd_tr">
<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>
@@ -143,10 +166,9 @@ Future work
<br>
<p>Revised October 26th 2025</p>
<p>Revised July 27th 2005</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2025 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+199 -228
View File
@@ -3,22 +3,26 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.MultiIndex Documentation - Tutorial</title>
<link rel="stylesheet" href="style.css" type="text/css">
<title>Boost.MultiIndex Documentation - Tutorial - Basics</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<link rel="start" href="../index.html">
<link rel="prev" href="index.html">
<link rel="up" href="index.html">
<link rel="next" href="indices.html">
</head>
<body>
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Tutorial</h1>
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Basics</h1>
<div class="prev_link"><a href="index.html"><img src="prev.gif" alt="index" border="0"><br>
Index
<div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
Index
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="advanced_topics.html"><img src="next.gif" alt="advanced topics" border="0"><br>
Advanced topics
<div class="next_link"><a href="indices.html"><img src="../next.gif" alt="index types" border="0"><br>
Index types
</a></div><br clear="all" style="clear: all;">
<hr>
@@ -26,16 +30,15 @@ Advanced topics
<h2>Contents</h2>
<ul>
<li><a href="#rationale">Rationale</a></li>
<li><a href="#namespace">Namespace</a></li>
<li><a href="#intro">Introduction</a>
<ul>
<li><a href="#multipe_sort">Multiple sorts on a single set</a></li>
<li><a href="#multiple_sort">Multiple sorts on a single set</a></li>
<li><a href="#list_fast_lookup">A bidirectional list with fast lookup</a></li>
</ul>
</li>
<li><a href="#index_spec">Index specification</a></li>
<li><a href="#tagging">Tagging</a></li>
<li><a href="#iterator_access">Iterator access</a></li>
<li><a href="#index_types">Index types</a>
<ul>
<li><a href="#ord_indices">Ordered indices</a>
@@ -62,78 +65,6 @@ Advanced topics
<li><a href="#complexity">Complexity and exception safety</a></li>
</ul>
<h2><a name="rationale">Rationale</a></h2>
<p>
STL containers are designed around the concept that each container controls its
own collection of elements, giving access to them in a manner specified by the
container's type: so, an <code>std::set</code> maintains the elements ordered
by a specified sorting criterium, <code>std::list</code> allows for free
positioning of elements along a linear sequence, and so on.
</p>
<p>
Sometimes, the necessity arises of having different access interfaces
to the same underlying collection: for instance, some data might need to be
sorted according to more than one comparison predicate, or a bidirectional list
might benefit from a supplemental logarithmic lookup interface. In these
situations, programmers typically resort to manual compositions of different
containers, a solution that generally involves a fair amount of code
devoted to preserve the synchronization of the different parts of
the composition. Boost.MultiIndex allows for the specification of
<code>multi_index_container</code>s comprised of one or more <i>indices</i> with
different interfaces to the same collection of elements. The resulting constructs
are conceptually cleaner than manual compositions, and often perform much better.
An important design decision has been taken that the indices of a given
<code>multi_index_container</code> instantiation be specified at compile time: this
gives ample room for static type checking and code optimization.
</p>
<p>
Boost.MultiIndex takes inspiration from basic concepts of indexing arising in the
theory of relational databases, though it is not intended to provide a full-fledged
relational database framework. <code>multi_index_container</code> integrates seamlessly
into the STL container/algorithm design, and features some extra capabilities regarding
lookup operations and element updating which are useful extensions even for
single-indexed containers.
</p>
<p align="center">
<img src="multi_index_cont_example.png"
alt="diagram of a multi_index_container with three indices"
width="600" height="304"><br>
<b>Fig. 1: Diagram of a <code>multi_index_container</code> with three indices.</b>
</p>
<p>
The figure above depicts a <code>multi_index_container</code> composed of three indices:
the first two present a set-like interface to the elements sorted by
shape and id, respectively, while the latter index provides the functionality
of a bidirectional list in the spirit of <code>std::list</code>. These
indices act as "views" to the internal collection of elements, but they do not only
provide read access to the set: insertion/deletion methods are also implemented much
as those of <code>std::set</code>s or <code>std::list</code>s. Insertion of an
element through one given index will only succeed if the uniqueness constraints of all
indices are met.
</p>
<h2>
<a name="namespace">Namespace</a>
</h2>
<p>
All the types of Boost.MultiIndex reside in namespace <code>::boost::multi_index</code>.
Additionaly, the main class template <code>multi_index_container</code> and global functions
<code>get</code> and <code>project</code> are lifted to namespace <code>::boost</code>
by means of <code>using</code> declarations. For brevity of exposition, the fragments
of code in the documentation are written as if the following declarations were in effect:
</p>
<blockquote><pre>
<span class=keyword>using</span> <span class=keyword>namespace</span> <span class=special>::</span><span class=identifier>boost</span><span class=special>;</span>
<span class=keyword>using</span> <span class=keyword>namespace</span> <span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>;</span>
</pre></blockquote>
<h2><a name="intro">Introduction</a></h2>
<p>
@@ -141,13 +72,13 @@ We introduce the main concepts of Boost.MultiIndex through the study of
two typical use cases.
</p>
<h3><a name="multipe_sort">Multiple sorts on a single set</a></h3>
<h3><a name="multiple_sort">Multiple sorts on a single set</a></h3>
<p>
STL sets and multisets are varying-length containers where elements are efficiently
sorted according to a given comparison predicate. These container classes fall short
of functionality when the programmer wishes to efficiently sort and look up the elements
following a different sorting criterium. Consider for instance:
following a different sorting criterion. Consider for instance:
</p>
<blockquote><pre>
@@ -183,7 +114,7 @@ construct easily becomes unmaintainable.
<p>
Boost.MultiIndex features <a href="#ord_indices"><i>ordered indices</i></a>, which
sort the elements according to a particular key, and are designed to help programmers
in need of sequences of elements for which <i>more than one</i> sorting criteria are
in need of sequences of elements for which <i>more than one</i> sorting criterion is
relevant. We do so by defining a <code>multi_index_container</code>
instantiation composed of several ordered indices: each index, viewed in isolation,
behaves much as an ordered <code>std::set</code> (or <code>std::multiset</code>), whilst
@@ -192,6 +123,11 @@ thus can be solved with Boost.MultiIndex as follows:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>member</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=comment>// define a multiply indexed set with indices by id and name</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
@@ -217,12 +153,13 @@ thus can be solved with Boost.MultiIndex as follows:
<p>
Instead of a single comparison predicate type, as it happens for STL associative
containers, <code>multi_index_container</code> is passed a <i>typelist</i> of index
containers, <code>multi_index_container</code> is passed a
<a href="../reference/multi_index_container.html#multi_index_container">list</a> of index
specifications (<code>indexed_by</code>), each one inducing the corresponding index.
Indices are accessed via
<a href="reference/multi_index_container.html#index_retrieval"><code>get</code></a><code>&lt;N>()</code>
<a href="../reference/multi_index_container.html#index_retrieval"><code>get</code></a><code>&lt;N>()</code>
where <i>N</i> ranges between 0 and the number of comparison
predicates minus one. The functionality of index #0 can be accessed directly from an
predicates minus one. The functionality of index #0 can be accessed directly from a
<code>multi_index_container</code> object without using <code>get&lt;0>()</code>: for instance,
<code>es.begin()</code> is equivalent to <code>es.get&lt;0>().begin()</code>.
</p>
@@ -302,6 +239,11 @@ does precisely this through the combination of sequenced and ordered indices:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>sequenced_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=comment>// define a multi_index_container with a list-like index and an ordered index</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
@@ -326,7 +268,7 @@ does not show any advantage. The code for inserting the text into the container
does not change as sequenced indices provide an interface similar to that of
<code>std::list</code> (no explicit access to this index through
<code>get&lt;0>()</code> is needed as <code>multi_index_container</code> inherits the
functionality of index #0.) But the specification of an additional ordered index
functionality of index #0). But the specification of an additional ordered index
allows us to implement <code>occurrences</code> and <code>delete_word</code>
in a much more efficient manner:
</p>
@@ -363,7 +305,7 @@ complexity. The programmer can use index #0 for accessing the text as with
<p>
The indices of a <code>multi_index_container</code> instantiation are specified by
means of the <a href="reference/indices.html#indexed_by">
means of the <a href="../reference/indices.html#indexed_by">
<code>indexed_by</code></a> construct. For instance, the instantiation
</p>
@@ -397,7 +339,7 @@ we specifiy two indices, the first of <a href="#seq_indices">sequenced type</a>,
the second a non-unique <a href="#ord_indices">ordered index</a>. In general, we
can specify an arbitrary number of indices: each of the arguments of
<code>indexed_by</code> is called an
<a href="reference/indices.html#index_specification"><i>index specifier</i></a>.
<a href="../reference/indices.html#index_specification"><i>index specifier</i></a>.
Depending on the type of index being specified, the corresponding specifier
will need additional information: for instance, the specifiers <code>ordered_unique</code>
and <code>ordered_non_unique</code> are provided with a
@@ -455,9 +397,9 @@ first parameter of the corresponding index specifier. The following is a revised
</pre></blockquote>
<p>
Tags have to be passed inside the <code>tag</code> construct. Any type can be
used as a tag for an index, although in general one will choose names that are
descriptive of the index they are associated with. The tagging mechanism allows
Tags have to be passed inside the <a href="../reference/indices.html#tag"><code>tag</code></a>
construct. Any type can be used as a tag for an index, although in general one will choose
names that are descriptive of the index they are associated with. The tagging mechanism allows
us to write expressions like</p>
<blockquote><pre>
@@ -475,7 +417,7 @@ for instance,
<li><code>employee_set::nth_index&lt;1>::type</code> is the type of
index #1,</li>
<li><code>employee_set::index&lt;name>::type</code> is the type of the index
tagged with <code>name</code> (the same index #1 in this case.)</li>
tagged with <code>name</code> (the same index #1 in this case).</li>
</ul>
<code>get()</code>, on the other hand, is overloaded to serve both styles of access:
</p>
@@ -507,6 +449,43 @@ in the previous example can be rewritten to hold two different tags
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
<h2><a name="iterator_access">Iterator access</a></h2>
<p>
Each index of a <code>multi_index_container</code> uses its own
iterator types, which are different from those of other indices. As is
the rule with STL containers, these iterators are defined as nested
types of the index:
</p>
<blockquote><pre>
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span>
<span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;().</span><span class=identifier>find</span><span class=special>(</span><span class=string>&quot;Judy Smith&quot;</span><span class=special>);</span>
</pre></blockquote>
<p>
This kind of expressions can be rendered more readable by
means of user-defined <code>typedef</code>s:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>employee_set_by_name</span><span class=special>;</span>
<span class=identifier>employee_set_by_name</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span>
<span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;().</span><span class=identifier>find</span><span class=special>(</span><span class=string>&quot;Judy Smith&quot;</span><span class=special>);</span>
</pre></blockquote>
<p>
The iterators provided by every index are <i>constant</i>, that is, the elements they point to
cannot be mutated directly. This follows the interface of <code>std::set</code> for ordered
indices but might come as a surprise for other types such as sequenced indices, which are modeled after
<code>std::list</code>, where this limitation does not happen. This seemingly odd behavior
is imposed by the way <code>multi_index_container</code>s work; if elements were
allowed to be mutated indiscriminately, we could introduce inconsistencies
in the ordered indices of the <code>multi_index_container</code> without the container
being notified about it. Element modification is properly done by means of
<a href="#ord_updating">update operations</a> on any index.
</p>
<h2>
<a name="index_types">Index types</a>
</h2>
@@ -517,20 +496,25 @@ Currently, Boost.MultiIndex provides the following index types:
<li>Ordered indices sort the elements like <code>std::set</code>s do and
provide a similar interface. There are <i>unique</i> and <i>non-unique</i>
variants: the former do not allow for duplicates, while the latter permit
them (like <code>std::multiset</code>.)</li>
<li>Hashed indices provide fast access to the elements through hashing
tecnhiques, in a similar way as non-standard <code>hash_set</code>s provided
by some vendors. Recently, <i>unordered associative containers</i> have been
proposed as part of an extension of the C++ standard library known
in the standardization commitee as TR1. Hashed indices closely model this
proposal.</li>
them (like <code>std::multiset</code>).</li>
<li>Ranked indices are a variation of ordered indices providing extra capabilities
for querying and accessing elements based on their <i>rank</i> (the numerical position
they occupy in the index).
</li>
<li>Sequenced indices are modeled after the semantics and interface of
<code>std::list</code>: they arrange the elements as if in a bidirectional
list.</li>
<li>Hashed indices provide fast access to the elements through hashing
techniques, in a similar way as unordered associative containers
<code>std::unordered_set</code> (if duplicates are not allowed) and
<code>std::unordered_multiset</code> (if they are).</li>
<li>Random access indices provide an interface similar to that of
sequenced indices, and additionally feature random access iterators
and positional access to the elements.</li>
</ul>
The examples in the <a href="#intro">introduction</a> exercise ordered and sequenced
indices, which are the most commonly used; hashed indices are presented in the
<a href="advanced_topics.html#hashed_indices">advanced topics</a> section.
indices, which are the most commonly used; the other kinds of indices are presented
in the <a href="indices.html">index types</a> section of the tutorial.
</p>
<h3>
@@ -654,13 +638,13 @@ the sorting is performed. In most cases, one of the following two situations ari
<ul>
<li>The whole element serves as the key, as is the case of the first index
in <code>employee_set</code>. The predefined
<a href="reference/key_extraction.html#identity"><code>identity</code></a> predicate
<a href="key_extraction.html#identity"><code>identity</code></a> predicate
can be used here as a key extractor; <code>identity</code> returns as the key the
same object passed as argument.</li>
<li>The comparison is performed on a particular data member of the element; this
closely follows the specification of indices on a column of a table in relational
databases. Boost.MultiIndex provides
<a href="reference/key_extraction.html#member"><code>member</code></a>, which returns
<a href="key_extraction.html#member"><code>member</code></a>, which returns
as the key a member of the element specified by a given pointer.</li>
</ul>
As an example, consider again the definition of <code>employee_set</code>. The
@@ -688,78 +672,11 @@ we use <code>member</code> to extract the <code>name</code> part of the
</p>
<p>
Another common situation arises when the sorting is performed on the result
of a particular member function. This resembles the notion of
<i>calculated indices</i> supported by some relational databases.
In these cases, the key is not a data member of the element, but rather it is
a value returned by a particular member function. Boost.MultiIndex supports this
kind of key extraction through
<a href="reference/key_extraction.html#const_mem_fun"><code>const_mem_fun</code></a>.
Consider the following extension of our example where sorting on the third index
is based upon the length of the name field:
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>employee</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>id</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=identifier>employee</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>id</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>&amp;</span> <span class=identifier>name</span><span class=special>):</span><span class=identifier>id</span><span class=special>(</span><span class=identifier>id</span><span class=special>),</span><span class=identifier>name</span><span class=special>(</span><span class=identifier>name</span><span class=special>){}</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&lt;(</span><span class=keyword>const</span> <span class=identifier>employee</span><span class=special>&amp;</span> <span class=identifier>e</span><span class=special>)</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>id</span><span class=special>&lt;</span><span class=identifier>e</span><span class=special>.</span><span class=identifier>id</span><span class=special>;}</span>
<span class=comment>// returns the length of the name field</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>name_length</span><span class=special>()</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>name</span><span class=special>.</span><span class=identifier>size</span><span class=special>();}</span>
<span class=special>};</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=comment>// sort by employee::operator&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=comment>// sort by less&lt;string&gt; on name</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=comment>// sort by less&lt;int&gt; on name_length()</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=identifier>const_mem_fun</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name_length</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
<p><a href="examples.html#example2">Example 2</a> in the examples section
provides a complete program showing how to use <code>const_mem_fun</code>.
Almost always you will want to use a <code>const</code> member function,
since elements in a <code>multi_index_container</code> are treated as constant, much
as elements of an <code>std::set</code>. However, a
<a href="reference/key_extraction.html#mem_fun"><code>mem_fun</code></a>
counterpart is provided for use with non-constant member functions, whose
applicability is discussed on the paragraph on
<a href="advanced_topics.html#advanced_key_extractors">advanced features
of Boost.MultiIndex key extractors</a> in the advanced topics section.
<p>
<p>
More complex scenarios may require the use of
<i>composite keys</i> combining the results of several key extractors.
Composite keys are supported by Boost.MultiIndex through the
<a href="advanced_topics.html#composite_keys"><code>composite_key</code></a>
construct.
</p>
<p>
<code>identity</code>, <code>member</code> and <code>const_mem_fun</code>
(occasionally combined with <code>composite_key</code>) serve
most common situations in the design of a <code>multi_index_container</code>. However, the
user is free to provide her own key extractors in more exotic situations, as long as
these conform to the <a href="reference/key_extraction.html#key_extractors"><code>Key
Extractor</code></a> concept. For instance,
<a href="examples.html#example6">example 6</a> implements several key
extraction techniques called for when elements and/or keys are accessed via
pointers.
Apart from <code>identity</code> and <code>member</code>, Boost.MultiIndex provides
several other predefined key extractors and powerful ways to combine them.
Key extractors can also be defined by the user.
Consult the <a href="key_extraction.html">key extraction section</a> of
the tutorial for a more detailed exposition of this topic.
</p>
<h4><a name="comparison_predicates">Comparison predicates</a></h4>
@@ -848,8 +765,8 @@ comparison predicate
Here we are not only passing IDs instead of <code>employee</code> objects:
an alternative comparison predicate is passed as well. In general, lookup operations
of ordered indices are overloaded to accept
<a href="reference/ord_indices.html#set_operations"><i>compatible sorting
criteria</i></a>. The somewhat cumbersone definition of compatibility in this context
<a href="../reference/ord_indices.html#set_operations"><i>compatible sorting
criteria</i></a>. The somewhat cumbersome definition of compatibility in this context
is given in the reference, but roughly speaking we say that a comparison predicate
<code>C1</code> is compatible with <code>C2</code> if any sequence sorted by
<code>C2</code> is also sorted with respect to <code>C1</code>.
@@ -884,7 +801,7 @@ The following shows a more interesting use of compatible predicates:
Range searching, i.e. the lookup of all elements in a given interval, is a very
frequent operation for which standard <code>lower_bound</code> and
<code>upper_bound</code> can be resorted to, though in a cumbersome manner.
For instance, the following code retrieves the elements of an
For instance, the following code retrieves the elements of a
<code>multi_index_container&lt;double></code> in the interval [100,200]:
</p>
@@ -923,9 +840,9 @@ and error prone task.
</p>
<p>
The <a href="reference/ord_indices.html#range_operations"><code>range</code></a>
The <a href="../reference/ord_indices.html#range_operations"><code>range</code></a>
member function, often in combination with
<a href="../../../libs/lambda/index.html">Boost.Lambda</a> expressions, can
<a href="../../../../libs/lambda/index.html">Boost.Lambda</a> expressions, can
greatly help alleviate this situation:
</p>
@@ -961,7 +878,7 @@ One or both bounds can be omitted with the special <code>unbounded</code> marker
<h4><a name="ord_updating">Updating</a></h4>
<p>
The <a href="reference/ord_indices.html#replace"><code>replace</code></a> member function
The <a href="../reference/ord_indices.html#replace"><code>replace</code></a> member function
performs in-place replacement of a given element as the following example shows:
</p>
@@ -997,7 +914,7 @@ the updating (when retrieving it and inside <code>replace</code>). If elements
are expensive to copy, this may be quite a computational cost for the modification
of just a tiny part of the object. To cope with this situation, Boost.MultiIndex
provides an alternative updating mechanism called
<a href="reference/ord_indices.html#modify"><code>modify</code></a>:
<a href="../reference/ord_indices.html#modify"><code>modify</code></a>:
</p>
<blockquote><pre>
@@ -1034,18 +951,69 @@ original value is kept and the method returns without altering the container, bu
leaves no trace of the previous value of the element. Integrity constraints
thus lead to the following policy: when a collision happens in the
process of calling <code>modify</code>, the element is erased and the method returns
<code>false</code>. This difference in behavior between <code>replace</code> and
<code>modify</code> has to be considered by the programmer on a case-by-case basis.
<code>false</code>. There is a further version of <code>modify</code> which
accepts a <i>rollback</i> functor to undo the changes in case of collision:
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>change_id</span>
<span class=special>{</span>
<span class=identifier>change_id</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>new_id</span><span class=special>):</span><span class=identifier>new_id</span><span class=special>(</span><span class=identifier>new_id</span><span class=special>){}</span>
<span class=keyword>void</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>employee</span><span class=special>&amp;</span> <span class=identifier>e</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>e</span><span class=special>.</span><span class=identifier>id</span><span class=special>=</span><span class=identifier>new_id</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>private</span><span class=special>:</span>
<span class=keyword>int</span> <span class=identifier>new_id</span><span class=special>;</span>
<span class=special>};</span>
<span class=special>...</span>
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=...</span>
<span class=keyword>int</span> <span class=identifier>old_id</span><span class=special>=</span><span class=identifier>it</span><span class=special>-&gt;</span><span class=identifier>id</span><span class=special>;</span> <span class=comment>// keep the original id
// try to modify the id, restore it in case of collisions</span>
<span class=identifier>es</span><span class=special>.</span><span class=identifier>modify</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>change_id</span><span class=special>(</span><span class=number>321</span><span class=special>),</span><span class=identifier>change_id</span><span class=special>(</span><span class=identifier>old_id</span><span class=special>));</span>
</pre></blockquote>
<p>In the example, <code>change_id(old_id)</code> is invoked to restore the original
conditions when the modification results in collisions with some other element.
The differences in behavior between <code>replace</code>, <code>modify</code> and
<code>modify</code> with rollback have to be considered by the programmer on a
case-by-case basis to determine the best updating mechanism.
</p>
<p align="center">
<table cellspacing="0">
<caption><b>Behavior of the different updating mechanisms.</b></caption>
<tr>
<th align="center">updating function</th>
<th>If there is a collision...</th>
</tr>
<tr>
<td align="center"><code>replace(it,x)</code></td>
<td>replacement does not take place.</td>
</tr>
<tr class="odd_tr">
<td align="center"><code>modify(it,mod)</code></td>
<td>the element is erased.</td>
</tr>
<tr>
<td align="center"><code>modify(it,mod,back)</code></td>
<td><code>back</code> is used to restore the original conditions.
(If <code>back</code> throws, the element is erased.)
</td>
</tr>
</table>
</p>
<p>
A key-based version of <code>modify</code>, named
<a href="reference/ord_indices.html#modify_key"><code>modify_key</code></a>, is
provided as well. In this case, the modifying functor is passed a reference to
the <code>key_value</code> part of the element instead of the whole object. Note
that <code>modify_key</code> cannot be used for key extractors which return calculated
values instead of references to data members of the elements, such
as <code>const_mem_fun</code>.
Key-based versions of <code>modify</code>, named
<a href="../reference/ord_indices.html#modify_key"><code>modify_key</code></a>, are
provided as well. In this case, the modifying functors are passed a reference to
the <code>key_type</code> part of the element instead of the whole object.
</p>
<blockquote><pre>
@@ -1071,10 +1039,10 @@ as <code>const_mem_fun</code>.
</pre></blockquote>
<p>
Just as <code>modify</code> does, <code>modify_key</code> erases the element if
the modification results in collisions in some index. <code>modify</code> and
Like <code>modify</code>, there are versions of <code>modify_key</code> with and
without rollback. <code>modify</code> and
<code>modify_key</code> are particularly well suited to use in conjunction to
<a href="../../../libs/lambda/index.html">Boost.Lambda</a>
<a href="../../../../libs/lambda/index.html">Boost.Lambda</a>
for defining the modifying functors:
</p>
@@ -1088,6 +1056,13 @@ for defining the modifying functors:
<span class=identifier>name_index</span><span class=special>.</span><span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>_1</span><span class=special>=</span><span class=string>&quot;Anna Smith&quot;</span><span class=special>);</span>
</pre></blockquote>
<p>
<code>modify_key</code> requires that the key extractor be of
a special type called
<a href="key_extraction.html#read_write_key_extractors">read/write</a>:
this is usually, but not always, the case.
</p>
<h3>
<a name="seq_indices">Sequenced indices</a>
</h3>
@@ -1099,27 +1074,23 @@ same way as <code>std::list</code> permits. The interface of sequenced indices
is thus designed upon that of <code>std::list</code>; nearly every operation
provided in the standard container is replicated here, occasionally with changes
in the syntax and/or semantics to cope with the constraints imposed by
Boost.MultiIndex. In particular, there is an important limitation of sequenced
indices with respect to <code>std::list</code>s, namely that elements of an
<code>multi_index_container</code> are not mutable through an iterator:
Boost.MultiIndex. An important difference, commented <a href="#iterator_access">above</a>,
is the fact that the values pointed to by sequenced index iterators are treated
as <i>constant</i>:
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>s</span><span class=special>;</span> <span class=comment>// list-like container</span>
<span class=special>&gt;</span> <span class=identifier>s</span><span class=special>;</span> <span class=comment>// list-like container</span>
<span class=identifier>s</span><span class=special>.</span><span class=identifier>push_front</span><span class=special>(</span><span class=number>0</span><span class=special>);</span>
<span class=special>*(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>())==</span><span class=number>1</span><span class=special>;</span> <span class=comment>// ERROR: the element cannot be changed</span>
<span class=special>*(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>())=</span><span class=number>1</span><span class=special>;</span> <span class=comment>// ERROR: the element cannot be changed</span>
</pre></blockquote>
<p>
That is, iterators of a sequenced index (of all types of indices, actually)
point to constant elements. This limitation might come as a surprise, but
it is imposed by the way <code>multi_index_container</code>s work; if elements were
allowed to be changed in this manner, we could introduce inconsistencies
in other ordered indices of the <code>multi_index_container</code>. Element modification
As with any other type of index, element modification
can nevertheless be done by means of
<a href="#seq_updating">update operations</a>.
</p>
@@ -1178,15 +1149,15 @@ do not always coincide with those of the standard container. Differences
result mainly from the fact that insertions into a sequenced index are not
guaranteed to succeed, due to the possible banning by other indices
of the <code>multi_index_container</code>. Consult the
<a href="reference/seq_indices.html">reference</a> for further details.
<a href="../reference/seq_indices.html">reference</a> for further details.
</p>
<h4><a name="seq_updating">Updating</a></h4>
<p>
Like ordered indices, sequenced indices provide
<a href="reference/seq_indices.html#replace"><code>replace</code></a> and
<a href="reference/seq_indices.html#modify"><code>modify</code></a>
<a href="../reference/seq_indices.html#replace"><code>replace</code></a> and
<a href="../reference/seq_indices.html#modify"><code>modify</code></a>
operations, with identical functionality. There is however no analogous
<code>modify_key</code>, since sequenced indices are not key-based.
</p>
@@ -1195,7 +1166,7 @@ operations, with identical functionality. There is however no analogous
<p>
Given indices <code>i1</code> and <code>i2</code> on the same <code>multi_index_container</code>,
<a href="reference/multi_index_container.html#projection"><code>project</code></a> can be used to
<a href="../reference/multi_index_container.html#projection"><code>project</code></a> can be used to
retrieve an <code>i2</code>-iterator from an <code>i1</code>-iterator, both of them
pointing to the same element of the container. This functionality allows the programmer to
move between different indices of the same <code>multi_index_container</code> when performing
@@ -1228,7 +1199,7 @@ A slightly more interesting example:
<span class=comment>// prepend &quot;older&quot; to all occurrences of &quot;sister&quot;</span>
<span class=identifier>text_container</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>it1</span><span class=special>=</span>
<span class=identifier>text_container</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it1</span><span class=special>=</span>
<span class=identifier>sorted_index</span><span class=special>.</span><span class=identifier>lower_bound</span><span class=special>(</span><span class=string>&quot;sister&quot;</span><span class=special>);</span>
<span class=keyword>while</span><span class=special>(</span><span class=identifier>it1</span><span class=special>!=</span><span class=identifier>sorted_index</span><span class=special>.</span><span class=identifier>end</span><span class=special>()&amp;&amp;*</span><span class=identifier>it1</span><span class=special>==</span><span class=string>&quot;sister&quot;</span><span class=special>){</span>
@@ -1257,33 +1228,33 @@ is preserved in the face of insertions, even for replace and modify operations.
Appropriate instantiations of <code>multi_index_container</code> can in fact simulate
<code>std::set</code>, <code>std::multiset</code> and (with more limitations)
<code>std::list</code>, as shown in the
<a href="advanced_topics.html#simulate_std_containers">advanced topics</a>
section. These simulations are as nearly as efficient as the original STL
containers; consult the <a href="reference/index.html">reference</a> for further
<a href="techniques.html#emulate_std_containers">techniques</a>
section. These simulations are nearly as efficient as the original STL
containers; consult the <a href="../reference/index.html">reference</a> for further
information on complexity guarantees and the
<a href="performance.html">performance section</a> for practical measurements of
<a href="../performance.html">performance section</a> for practical measurements of
efficiency.
</p>
<hr>
<div class="prev_link"><a href="index.html"><img src="prev.gif" alt="index" border="0"><br>
Index
<div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="tutorial" border="0"><br>
Boost.MultiIndex Tutorial
</a></div>
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
Index
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="advanced_topics.html"><img src="next.gif" alt="advanced topics" border="0"><br>
Advanced topics
<div class="next_link"><a href="indices.html"><img src="../next.gif" alt="index types" border="0"><br>
Index types
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised March 31st 2005</p>
<p>Revised August 16th 2021</p>
<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2021 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
License, 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>
+353
View File
@@ -0,0 +1,353 @@
<!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 - Tutorial - Container creation</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<link rel="start" href="../index.html">
<link rel="prev" href="key_extraction.html">
<link rel="up" href="index.html">
<link rel="next" href="debug.html">
</head>
<body>
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Container creation</h1>
<div class="prev_link"><a href="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="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="debug.html"><img src="../next.gif" alt="debugging support" border="0"><br>
Debugging support
</a></div><br clear="all" style="clear: all;">
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#value_semantics">Value semantics</a></li>
<li><a href="#ctor_args_list">Use of <code>ctor_args_list</code></a></li>
<li><a href="#special_allocator">Special allocator support</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
<h2><a name="value_semantics">Value semantics</a></h2>
<p>
<code>multi_index_container</code>s have the usual value semantics associated
to copy construction and assignment, i.e. copies of the elements from the source
container are created and inserted into the destination container.
More interestingly, copying also recreates the original order in which
elements are arranged for <i>every index</i> of the container.
This implies that equality of all indices is preserved under copying
or assignment, for those index types where equality is defined. This behavior
can be regarded as a natural extension to the general rule on copy semantics
stating that if <code>y</code> is a copy of <code>x</code>, then
<code>y==x</code>.
</p>
<h2><a name="ctor_args_list">Use of <code>ctor_args_list</code></a></h2>
<p>
Although in most cases <code>multi_index_container</code>s will be default constructed
(or copied from a preexisting <code>multi_index_container</code>), sometimes it is
necessary to specify particular values for the internal objects used (key extractors,
comparison predicates, allocator), for instance if some of these objects do not have
a default constructor. The same situation can arise with standard STL containers,
which allow for the optional specification of such objects:
</p>
<blockquote><pre>
<span class=comment>// example of non-default constructed std::set</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>IntegralType</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>modulo_less</span>
<span class=special>{</span>
<span class=identifier>modulo_less</span><span class=special>(</span><span class=identifier>IntegralType</span> <span class=identifier>m</span><span class=special>):</span><span class=identifier>modulo</span><span class=special>(</span><span class=identifier>m</span><span class=special>){}</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>IntegralType</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>IntegralType</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=special>(</span><span class=identifier>x</span><span class=special>%</span><span class=identifier>modulo</span><span class=special>)&lt;(</span><span class=identifier>y</span><span class=special>%</span><span class=identifier>modulo</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>private</span><span class=special>:</span>
<span class=identifier>IntegralType</span> <span class=identifier>modulo</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>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>,</span><span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>modulo_set</span><span class=special>;</span>
<span class=identifier>modulo_set</span> <span class=identifier>m</span><span class=special>(</span><span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;(</span><span class=number>10</span><span class=special>));</span>
</pre></blockquote>
<p>
<code>multi_index_container</code> does also provide this functionality, though in a
considerably more complex fashion, due to the fact that the constructor
of a <code>multi_index_container</code> has to accept values for all the internal
objects of its indices. The full form of <code>multi_index_container</code> constructor
is
</p>
<blockquote><pre>
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
</pre></blockquote>
<p>
The specification of the allocator object poses no particular problems;
as for the <code>ctor_args_list</code>, this object is designed so as to hold
the necessary construction values for every index in the <code>multi_index_container</code>.
From the point of view of the user, <code>ctor_args_list</code> is equivalent
to the type
</p>
<blockquote><pre>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>C<sub>0</sub></span><span class=special>,...,</span><span class=identifier>C<sub>I-1</sub></span><span class=special>&gt;</span>
</pre></blockquote>
<p>
where <code>I</code> is the number of indices, and <code>C<sub>i</sub></code> is
</p>
<blockquote><pre>
<span class=identifier>nth_index</span><span class=special>&lt;</span><span class=identifier>i</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span>
</pre></blockquote>
<p>
that is, the nested type <code>ctor_args</code> of the <code>i</code>-th index. Each
<code>ctor_args</code> type is in turn a tuple holding values for constructor
arguments of the associated index: so, ordered indices demand a key extractor object
and a comparison predicate, hashed indices take an initial number of buckets,
a key extractor, a hash function and an equality predicate; while sequenced
and random access indices do not need any construction argument. For instance,
given the definition
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>hashed_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;,</span> <span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
<span class=identifier>random_access</span><span class=special>&lt;&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>modulo_indexed_set</span><span class=special>;</span>
</pre></blockquote>
<p>
the corresponding <code>ctor_args_list</code> type is equivalent to
</p>
<blockquote><pre>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span>
<span class=comment>// ctr_args of index #0</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span><span class=special>,</span> <span class=comment>// initial number of buckets; 0 if unspecified</span>
<span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;,</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=comment>// ctr_args of index #1</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span>
<span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;,</span>
<span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=comment>// sequenced indices do not have any construction argument</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;&gt;,</span>
<span class=comment>// neither do random access indices</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;&gt;</span>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
Such a <code>modulo_indexed_set</code> cannot be default constructed, because
<code>modulo_less</code> does not provide a default constructor. The following shows
how the construction can be done:
</p>
<blockquote><pre>
<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>ctor_args_list</span> <span class=identifier>args_list</span><span class=special>=</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>make_tuple</span><span class=special>(</span>
<span class=comment>// ctor_args for index #0 is default constructible</span>
<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>0</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>(),</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>make_tuple</span><span class=special>(</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;(),</span><span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;(</span><span class=number>10</span><span class=special>)),</span>
<span class=comment>// these are also default constructible (actually, empty tuples)</span>
<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>2</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>(),</span>
<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>3</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>()</span>
<span class=special>);</span>
<span class=identifier>modulo_indexed_set</span> <span class=identifier>m</span><span class=special>(</span><span class=identifier>args_list</span><span class=special>);</span>
</pre></blockquote>
<p>
A program is provided in the <a href="../examples.html#example3">examples section</a> that
puts in practise these concepts.
</p>
<h2><a name="special_allocator">Special allocator support</a></h2>
<p>
Boost.MultiIndex allows for a slightly more general class of allocators
than strictly required by the C++ standard, as explained in detail in the
<a href="../reference/multi_index_container.html#instantiation_types">reference</a>.
An important type of non-standard allocators supported are those provided by the
<a href="../../../interprocess/index.html">Boost Interprocess Library</a>;
this opens up the possibility of placing <code>multi_index_container</code>s
and their iterators in shared memory.
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>allocators</span><span class=special>/</span><span class=identifier>allocator</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>managed_shared_memory</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>bip</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>interprocess</span><span class=special>;</span>
<span class=comment>// a shared memory compatible allocator of ints</span>
<span class=keyword>typedef</span> <span class=identifier>bip</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span><span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span><span class=special>::</span><span class=identifier>segment_manager</span>
<span class=special>&gt;</span> <span class=identifier>shared_int_allocator</span><span class=special>;</span>
<span class=comment>// define a shared memory compatible multi_index_container
// using shared_int_allocator</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;,</span>
<span class=identifier>shared_int_allocator</span>
<span class=special>&gt;</span> <span class=identifier>unique_int_list</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// create a managed memory segment</span>
<span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span> <span class=identifier>seg</span><span class=special>(</span>
<span class=identifier>bip</span><span class=special>::</span><span class=identifier>create_only</span><span class=special>,</span><span class=string>&quot;SharedMemoryID&quot;</span><span class=special>,</span><span class=number>65536</span><span class=special>);</span>
<span class=comment>// construct a unique_int_list into the segment</span>
<span class=identifier>unique_int_list</span><span class=special>*</span> <span class=identifier>puil</span><span class=special>=</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>construct</span><span class=special>&lt;</span><span class=identifier>unique_int_list</span><span class=special>&gt;</span>
<span class=special>(</span><span class=string>&quot;UniqueIntListID&quot;</span><span class=special>)</span> <span class=comment>// object identifier within the segment
// Construction args: first a ctor arg list, then a
// shared memory allocator obtained from the segment object.</span>
<span class=special>(</span><span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
<span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>allocator_type</span><span class=special>(</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>get_segment_manager</span><span class=special>()));</span>
</pre></blockquote>
<p>
The examples section includes a <a href="../examples.html#example12">program</a>
that further explores this capability.
</p>
<h2><a name="serialization">Serialization</a></h2>
<p>
<code>multi_index_container</code>s can be archived and retrieved by means of the
<a href="../../../serialization/index.html">Boost Serialization Library</a>. Both regular
and XML archives are supported. The usage is straightforward and does not
differ from that of any other serializable type. For instance:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>archive</span><span class=special>/</span><span class=identifier>text_oarchive</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>archive</span><span class=special>/</span><span class=identifier>text_iarchive</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>fstream</span><span class=special>&gt;</span>
<span class=special>...</span>
<span class=keyword>void</span> <span class=identifier>save</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>es</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>ofstream</span> <span class=identifier>ofs</span><span class=special>(</span><span class=string>&quot;data&quot;</span><span class=special>);</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>archive</span><span class=special>::</span><span class=identifier>text_oarchive</span> <span class=identifier>oa</span><span class=special>(</span><span class=identifier>ofs</span><span class=special>);</span>
<span class=identifier>oa</span><span class=special>&lt;&lt;</span><span class=identifier>es</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>void</span> <span class=identifier>load</span><span class=special>(</span><span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>es</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>ifstream</span> <span class=identifier>ifs</span><span class=special>(</span><span class=string>&quot;data&quot;</span><span class=special>);</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>archive</span><span class=special>::</span><span class=identifier>text_iarchive</span> <span class=identifier>ia</span><span class=special>(</span><span class=identifier>ifs</span><span class=special>);</span>
<span class=identifier>ia</span><span class=special>&gt;&gt;</span><span class=identifier>es</span><span class=special>;</span>
<span class=special>}</span>
<span class=special>...</span>
<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
<span class=special>...</span> <span class=comment>// fill it with data</span>
<span class=identifier>save</span><span class=special>(</span><span class=identifier>es</span><span class=special>);</span>
<span class=special>...</span>
<span class=identifier>employee_set</span> <span class=identifier>restored_es</span><span class=special>;</span>
<span class=identifier>load</span><span class=special>(</span><span class=identifier>restored_es</span><span class=special>);</span>
</pre></blockquote>
<p>
Serialization capabilities are automatically provided by just linking with
the appropriate Boost.Serialization library module: it is not necessary
to explicitly include any header from Boost.Serialization,
apart from those declaring the type of archive used in the process. If not used,
however, serialization support can be disabled by globally defining the macro
<code>BOOST_MULTI_INDEX_DISABLE_SERIALIZATION</code>. Disabling serialization
for Boost.MultiIndex can yield a small improvement in build times, and may
be necessary in those defective compilers that fail to correctly process
Boost.Serialization headers.
</p>
<p>
In accordance with Boost.MultiIndex
<a href="#value_semantics">value semantics</a>, retrieving an
archived <code>multi_index_container</code> restores not only
the elements, but also the order they were arranged into for
every index of the container. There is an exception to this rule,
though: for <a href="indices.html#hashed_indices">hashed
indices</a>, no guarantee is made about the order in which elements will
be iterated in the restored container; in general, it is unwise to rely on
the ordering of elements of a hashed index, since it can change in arbitrary
ways during insertion or rehashing --this is precisely the reason why
hashed indices and TR1 unordered associative containers do not define
an equality operator.
</p>
<p>
Iterators to indices of a <code>multi_index_container</code> can also be
serialized. Serialization of iterators must be done only after serializing
their corresponding container.
</p>
<p>
<a href="../examples.html#example9">Example 9</a> in the examples section shows
the serialization capabilities of Boost.MultiIndex.
</p>
<hr>
<div class="prev_link"><a href="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="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="debug.html"><img src="../next.gif" alt="debugging support" border="0"><br>
Debugging support
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2026 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>
+274
View File
@@ -0,0 +1,274 @@
<!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 - Tutorial -Debugging support</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<link rel="start" href="../index.html">
<link rel="prev" href="creation.html">
<link rel="up" href="index.html">
<link rel="next" href="techniques.html">
</head>
<body>
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Debugging support</h1>
<div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br>
Container creation
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br>
Techniques
</a></div><br clear="all" style="clear: all;">
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#debugging_support">Debugging support</a></li>
<li><a href="#safe_mode">Safe mode</a>
<ul>
<li><a href="#serialization_and_safe_mode">Serialization and safe mode</a></li>
<li><a href="#shared_memory_and_safe_mode">Containers placed in shared memory</a></li>
</ul>
</li>
<li><a href="#invariant_check">Invariant-checking mode</a></li>
</ul>
<h2><a name="debugging_support">Debugging support</a></h2>
<p>
The concept of <i>Design by Contract</i>, originally developed as part
of Bertrand Meyer's <a href="http://www.eiffel.com">Eiffel</a> language,
revolves around the formulation of a <i>contract</i> between the user
of a library and the implementor, by which the first is required to
respect some <i>preconditions</i> on the values passed when invoking
methods of the library, and the implementor guarantees in return
that certain constraints on the results are met (<i>postconditions</i>),
as well as the honoring of specified internal consistency rules, called
<i>invariants</i>. Eiffel natively supports the three parts of the
contract just described by means of constructs <code>require</code>,
<code>ensure</code> and <code>invariant</code>, respectively.
</p>
<p>
C++ does not enjoy direct support for Design by Contract techniques: these
are customarily implemented as assertion code, often turned off in
release mode for performance reasons. Following this approach,
Boost.MultiIndex provides two distinct debugging modes:
<ul>
<li><i>Safe mode</i> checks preconditions on the invocations to the
facilities of the library,</li>
<li><i>invariant-checking mode</i> performs post-execution checks aimed
at ensuring that the internal consistency of the library is preserved.</li>
</ul>
These two modes are independent of each other and can be set on or off
individually. It is important to note that errors detected by safe mode are
due in principle to faulty code in the user's program, while
invariant-checking mode detects potential <i>internal</i> bugs in the
implementation of Boost.MultiIndex.
</p>
<h2><a name="safe_mode">Safe mode</a></h2>
<p>
The idea of adding precondition checking facilities to STL as a debugging aid
was first introduced by Cay S. Horstmann in his
<a href="http://www.horstmann.com/safestl.html">Safe STL</a> library and later
adopted by <a href="http://www.stlport.com/doc/debug_mode.html">STLport Debug
Mode</a>. Similarly, Boost.MultiIndex features the so-called <i>safe mode</i>
in which all sorts of preconditions are checked when dealing with iterators
and functions of the library.
</p>
<p>
Boost.MultiIndex safe mode is set by globally defining the macro
<code>BOOST_MULTI_INDEX_ENABLE_SAFE_MODE</code>. Error conditions
are checked via the macro <code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, which
by default resolves to a call to <a href="../../../../libs/assert">
<code>BOOST_ASSERT</code></a>.
</p>
<p>
If the user decides to define her own version of
<code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, it has to take the form
</p>
<blockquote><pre>
<span class=identifier>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</span><span class=special>(</span><span class=identifier>expr</span><span class=special>,</span><span class=identifier>error_code</span><span class=special>)</span>
</pre></blockquote>
<p>
where <code>expr</code> is the condition checked and <code>error_code</code>
is one value of the <code>safe_mode::error_code</code> enumeration:
</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>safe_mode</span><span class=special>{</span>
<span class=keyword>enum</span> <span class=identifier>error_code</span>
<span class=special>{</span>
<span class=identifier>invalid_iterator</span><span class=special>,</span> <span class=comment>// vg. default cted or pointing to erased element</span>
<span class=identifier>not_dereferenceable_iterator</span><span class=special>,</span> <span class=comment>// iterator is not dereferenceable</span>
<span class=identifier>not_incrementable_iterator</span><span class=special>,</span> <span class=comment>// iterator points to end of sequence</span>
<span class=identifier>not_decrementable_iterator</span><span class=special>,</span> <span class=comment>// iterator points to beginning of sequence</span>
<span class=identifier>not_owner</span><span class=special>,</span> <span class=comment>// iterator does not belong to the container</span>
<span class=identifier>not_same_owner</span><span class=special>,</span> <span class=comment>// iterators belong to different containers</span>
<span class=identifier>invalid_range</span><span class=special>,</span> <span class=comment>// last not reachable from first</span>
<span class=identifier>inside_range</span><span class=special>,</span> <span class=comment>// iterator lies within a range (and it mustn't)</span>
<span class=identifier>out_of_bounds</span><span class=special>,</span> <span class=comment>// move attempted beyond container limits</span>
<span class=identifier>same_container</span><span class=special>,</span> <span class=comment>// containers ought to be different</span>
<span class=identifier>unequal_allocators</span> <span class=comment>// allocators ought to be equal</span>
<span class=special>};</span>
<span class=special>}</span> <span class=comment>// namespace multi_index::safe_mode</span>
<span class=special>}</span> <span class=comment>// namespace multi_index</span>
<span class=special>}</span> <span class=comment>// namespace boost</span>
</pre></blockquote>
<p>
For instance, the following replacement of
<code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code> throws an exception instead of
asserting:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>/</span><span class=identifier>safe_mode_errors</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>safe_mode_exception</span>
<span class=special>{</span>
<span class=identifier>safe_mode_exception</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>safe_mode</span><span class=special>::</span><span class=identifier>error_code</span> <span class=identifier>error_code</span><span class=special>):</span>
<span class=identifier>error_code</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>)</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>safe_mode</span><span class=special>::</span><span class=identifier>error_code</span> <span class=identifier>error_code</span><span class=special>;</span>
<span class=special>};</span>
<span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</span><span class=special>(</span><span class=identifier>expr</span><span class=special>,</span><span class=identifier>error_code</span><span class=special>)</span> <span class=special>\</span>
<span class=keyword>if</span><span class=special>(!(</span><span class=identifier>expr</span><span class=special>)){</span><span class=keyword>throw</span> <span class=identifier>safe_mode_exception</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>);}</span>
<span class=comment>// This has to go before the inclusion of any header from Boost.MultiIndex,
// except possibly safe_error_codes.hpp.</span>
</pre></blockquote>
<p>
Other possibilities, like outputting to a log or firing some kind of alert, are
also implementable.
</p>
<p>
<b>Warning:</b> Safe mode adds a very important overhead to the program
both in terms of space and time used, so in general it should not be set for
<code>NDEBUG</code> builds. Also, this mode is intended solely as a debugging aid,
and programs must not rely on it as part of their normal execution flow: in
particular, no guarantee is made that all possible precondition errors are diagnosed,
or that the checks remain stable across different versions of the library.
</p>
<h3><a name="serialization_and_safe_mode">Serialization and safe mode</a></h3>
<p>
Iterators restored from an archive are not subject to safe mode checks. This is
so because it is not possible to automatically know the associated
<code>multi_index_container</code> of an iterator from the serialization
information alone. However, if desired, a restored iterator can be converted to a
checked value by using the following workaround:
</p>
<blockquote><pre>
<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>;</span>
<span class=comment>// restore es and it from an archive ar</span>
<span class=identifier>ar</span><span class=special>&gt;&gt;</span><span class=identifier>es</span><span class=special>;</span>
<span class=identifier>ar</span><span class=special>&gt;&gt;</span><span class=identifier>it</span><span class=special>;</span> <span class=comment>// it won't benefit from safe mode checks
// Turn it into a checked value by providing Boost.MultiIndex
// with info about the associated container.
// This statement has virtually zero cost if safe mode is turned off.</span>
<span class=identifier>it</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>project</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
</pre></blockquote>
<h3><a name="shared_memory_and_safe_mode">Containers placed in shared memory</a></h3>
<p>
In general, safe mode <b>can't be used</b> when placing <code>multi_index_container</code>s
in shared memory for interprocess communication
(as in <a href="../examples.html#example12">this example</a>).
There are some fundamental reasons for this limitation:
<ul>
<li>
Operations from one process may invalidate or change ownership for iterators
living in non-shared memory within another process: safe-mode machinery can't
access those for bookkeeping.
</li>
<li>
Safe mode uses internal mutexes not suitable for interprocess
synchronization or persistence to a memory-mapped file.
</li>
</ul>
</p>
<h2><a name="invariant_check">Invariant-checking mode</a></h2>
<p>
The so called <i>invariant-checking mode</i> of Boost.MultiIndex can be
set by globally defining the macro
<code>BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING</code>.
When this mode is in effect, all public functions of Boost.MultiIndex
will perform post-execution tests aimed at ensuring that the basic
internal invariants of the data structures managed are preserved.
</p>
<p>
If an invariant test fails, Boost.MultiIndex will indicate the failure
by means of the unary macro <code>BOOST_MULTI_INDEX_INVARIANT_ASSERT</code>.
Unless the user provides a definition for this macro, it defaults to
<a href="../../../../libs/assert">
<code>BOOST_ASSERT</code></a>. Any assertion of this kind should
be regarded in principle as a bug in the library. Please report such
problems, along with as much contextual information as possible, to the
maintainer of the library.
</p>
<p>
It is recommended that users of Boost.MultiIndex always set the
invariant-checking mode in debug builds.
</p>
<hr>
<div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br>
Container creation
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br>
Techniques
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2026 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>
+139
View File
@@ -0,0 +1,139 @@
<!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 - Tutorial</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<link rel="start" href="../index.html">
<link rel="prev" href="../index.html">
<link rel="up" href="../index.html">
<link rel="next" href="basics.html">
</head>
<body>
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Tutorial</h1>
<div class="prev_link"><a href="../index.html"><img src="../prev.gif" alt="index" border="0"><br>
Index
</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="basics.html"><img src="../next.gif" alt="basics" border="0"><br>
Basics
</a></div><br clear="all" style="clear: all;">
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#rationale">Rationale</a></li>
<li><a href="#namespace">Namespace</a></li>
<li><a href="basics.html">Basics</a></li>
<li><a href="indices.html">Index types</a></li>
<li><a href="key_extraction.html">Key extraction</a></li>
<li><a href="creation.html">Container creation</a></li>
<li><a href="debug.html">Debugging support</a></li>
<li><a href="techniques.html">Techniques</a></li>
</ul>
<h2><a name="rationale">Rationale</a></h2>
<p>
STL containers are designed around the concept that each container controls its
own collection of elements, giving access to them in a manner specified by the
container's type: so, an <code>std::set</code> maintains the elements ordered
by a specified sorting criterion, <code>std::list</code> allows for free
positioning of elements along a linear sequence, and so on.
</p>
<p>
Sometimes, the necessity arises of having different access interfaces
to the same underlying collection: for instance, some data might need to be
sorted according to more than one comparison predicate, or a bidirectional list
might benefit from a supplemental logarithmic lookup interface. In these
situations, programmers typically resort to manual compositions of different
containers, a solution that generally involves a fair amount of code
devoted to preserve the synchronization of the different parts of
the composition. Boost.MultiIndex allows for the specification of
<code>multi_index_container</code>s comprised of one or more <i>indices</i> with
different interfaces to the same collection of elements. The resulting constructs
are conceptually cleaner than manual compositions, and often perform much better.
An important design decision has been taken that the indices of a given
<code>multi_index_container</code> instantiation be specified at compile time: this
gives ample room for static type checking and code optimization.
</p>
<p>
Boost.MultiIndex takes inspiration from basic concepts of indexing arising in the
theory of relational databases, though it is not intended to provide a full-fledged
relational database framework. <code>multi_index_container</code> integrates seamlessly
into the STL container/algorithm design, and features some extra capabilities regarding
lookup operations and element updating which are useful extensions even for
single-indexed containers.
</p>
<p align="center">
<img src="multi_index_cont_example.png"
alt="diagram of a multi_index_container with three indices"
width="600" height="304"><br>
<b>Fig. 1: Diagram of a <code>multi_index_container</code> with three indices.</b>
</p>
<p>
The figure above depicts a <code>multi_index_container</code> composed of three indices:
the first two present a set-like interface to the elements sorted by
shape and id, respectively, while the latter index provides the functionality
of a bidirectional list in the spirit of <code>std::list</code>. These
indices act as "views" to the internal collection of elements, but they do not only
provide read access to the set: insertion/deletion methods are also implemented much
as those of <code>std::set</code>s or <code>std::list</code>s. Insertion of an
element through one given index will only succeed if the uniqueness constraints of all
indices are met.
</p>
<h2>
<a name="namespace">Namespace</a>
</h2>
<p>
All the public types of Boost.MultiIndex reside in namespace <code>::boost::multi_index</code>.
Additionally, the main class template <code>multi_index_container</code> and global functions
<code>get</code> and <code>project</code> are lifted to namespace <code>::boost</code>
by means of <code>using</code> declarations. For brevity of exposition, the fragments
of code in the documentation are written as if the following declarations were in effect:
</p>
<blockquote><pre>
<span class=keyword>using</span> <span class=keyword>namespace</span> <span class=special>::</span><span class=identifier>boost</span><span class=special>;</span>
<span class=keyword>using</span> <span class=keyword>namespace</span> <span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>;</span>
</pre></blockquote>
<hr>
<div class="prev_link"><a href="../index.html"><img src="../prev.gif" alt="index" border="0"><br>
Index
</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="basics.html"><img src="../next.gif" alt="basics" border="0"><br>
Basics
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised February 21st 2006</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>
+942
View File
@@ -0,0 +1,942 @@
<!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 - Tutorial - Index types</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<link rel="start" href="../index.html">
<link rel="prev" href="basics.html">
<link rel="up" href="index.html">
<link rel="next" href="key_extraction.html">
</head>
<body>
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Index types</h1>
<div class="prev_link"><a href="basics.html"><img src="../prev.gif" alt="basics" border="0"><br>
Basics
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="key_extraction.html"><img src="../next.gif" alt="key estraction" border="0"><br>
Key extraction
</a></div><br clear="all" style="clear: all;">
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#classification">Classification</a>
<li><a href="#rnk_indices">Ranked indices</a>
<ul>
<li><a href="#rnk_spec">Specification</a></li>
<li><a href="#rnk_ops">Rank operations</a></li>
</ul>
</li>
<li><a href="#hashed_indices">Hashed indices</a>
<ul>
<li><a href="#hash_unique_non_unique">Unique and non-unique variants</a></li>
<li><a href="#hash_spec">Specification</a></li>
<li><a href="#hash_lookup">Lookup</a></li>
<li><a href="#hash_updating">Updating</a></li>
<li><a href="#guarantees">Guarantees on iterator validity and exception safety</a></li>
</ul>
</li>
<li><a href="#rnd_indices">Random access indices</a>
<ul>
<li><a href="#rnd_spec">Specification</a></li>
<li><a href="#rnd_interface">Interface</a></li>
<li><a href="#rnd_vs_vector">Comparison with <code>std::vector</code></a></li>
</ul>
</li>
<li><a href="#rearrange">Index rearranging</a></li>
<li><a href="#iterator_to"><code>iterator_to</code></a></li>
<li><a href="#node_handling">Node handling operations</a></li>
<li><a href="#ordered_node_compression">Ordered indices node compression</a></li>
</ul>
<h2><a name="classification">Classification</a></h2>
<p>
Boost.MultiIndex provides eight different index types, which can be classified as
shown in the table below. <a href="basics.html#ord_indices">Ordered</a> and
<a href="basics.html#seq_indices">sequenced</a> indices,
which are the most commonly used, have been explained in the basics section;
the rest of index types can be regarded as variations of the former providing
some added benefits, functionally or in the area of performance.
</p>
<p align="center">
<table cellspacing="0">
<caption><b>Boost.MultiIndex indices.</b></caption>
<tr>
<th align="center"colspan="2">type</th>
<th align="center">specifier</th>
</tr>
<tr>
<td align="center" rowspan="6">&nbsp;&nbsp;key-based&nbsp;&nbsp;</td>
<td align="center" rowspan="4">&nbsp;&nbsp;ordered&nbsp;&nbsp;</td>
<td align="center">&nbsp;&nbsp;<code>ordered_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr class="odd_tr">
<td align="center">&nbsp;&nbsp;<code>ordered_non_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr>
<td align="center">&nbsp;&nbsp;<code>ranked_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr class="odd_tr">
<td align="center">&nbsp;&nbsp;<code>ranked_non_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr>
<td align="center" rowspan="2">&nbsp;&nbsp;hashed&nbsp;&nbsp;</td>
<td align="center">&nbsp;&nbsp;<code>hashed_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr class="odd_tr">
<td align="center">&nbsp;&nbsp;<code>hashed_non_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr>
<td align="center" rowspan="2" colspan="2">&nbsp;&nbsp;non key-based&nbsp;&nbsp;</td>
<td align="center"><code>&nbsp;&nbsp;sequenced&nbsp;&nbsp;</code></td>
</tr>
<tr class="odd_tr">
<td align="center"><code>&nbsp;&nbsp;random_access&nbsp;&nbsp;</code></td>
</tr>
</table>
</p>
<p>
Key-based indices, of which ordered indices are the usual example, provide
efficient lookup of elements based on some piece of information called the
<i>element key</i>: there is an extensive suite of
<a href="key_extraction.html">key extraction</a>
utility classes allowing for the specification of such keys. Fast lookup
imposes an internally managed order on these indices that the user is not
allowed to modify; non key-based indices, on the other hand, can be freely
rearranged at the expense of lacking lookup facilities. Sequenced indices,
modeled after the interface of <code>std::list</code>, are the customary
example of a non key-based index.
</p>
<h2><a name="rnk_indices">Ranked indices</a></h2>
<p>
Suppose we have a <code>std::multiset</code> of numbers and we want to output
the values above the 75h <a href="http://en.wikipedia.org/wiki/Percentile">percentile</a>:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=identifier>int_multiset</span><span class=special>;</span>
<span class=keyword>void</span> <span class=identifier>output_above_75th_percentile</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>int_multiset</span><span class=special>&amp;</span> <span class=identifier>s</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>();</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>advance</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</span><span class=special>()*</span><span class=number>3</span><span class=special>/</span><span class=number>4</span><span class=special>);</span> <span class=comment>// linear on s.size();</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>copy</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream_iterator</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>,</span><span class=string>&quot;\n&quot;</span><span class=special>));</span>
<span class=special>}</span>
</pre></blockquote>
<p>
The problem with this code is that getting to the beginning of the desired subsequence
involves a linear traversal of the container. Ranked indices provide the mechanisms to do this
much faster:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ranked_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>int_multiset</span><span class=special>;</span>
<span class=keyword>void</span> <span class=identifier>output_above_75th_percentile</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>int_multiset</span><span class=special>&amp;</span> <span class=identifier>s</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>nth</span><span class=special>(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</span><span class=special>()*</span><span class=number>3</span><span class=special>/</span><span class=number>4</span><span class=special>);</span> <span class=comment>// logarithmic</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>copy</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream_iterator</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>,</span><span class=string>&quot;\n&quot;</span><span class=special>));</span>
<span class=special>}</span>
</pre></blockquote>
<p>
<code>nth(n)</code> returns an iterator to the element whose <i>rank</i>, i.e. its distance
from the beginning of the index, is <code>n</code>, and does so efficiently in logarithmic time.
Conversely, <code>rank(it)</code> computes in logarithmic time the rank of the element
pointed to by <code>it</code>, or <code>size()</code> if <code>it==end()</code>.
</p>
<blockquote><pre>
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</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=number>10</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>size_type</span> <span class=identifier>r</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>it</span><span class=special>);</span> <span class=comment>// rank of 10;</span>
</pre></blockquote>
<p>
Ranked indices provide the same interface as ordered indices plus several rank-related operations.
The cost of this extra functionality is higher memory consumption due to some internal additional
data (one word per element) and somewhat longer execution times in insertion and erasure
&#8212;in particular, erasing an element takes time proportional to <code>log(n)</code>, where
<code>n</code> is the number of elements in the index, whereas for ordered indices this time is
constant.
The <a href="../reference/rnk_indices.html">reference</a> describes these indices in complete detail.
</p>
<h3><a name="rnk_spec">Specification</a></h3>
<p>
The specification of ranked indices is done exactly as with <a href="basics.html#ord_spec">ordered indices</a>,
except that <code>ranked_unique</code> and <code>ranked_non_unique</code> are used instead.
</p>
<blockquote><pre>
<span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)
</span><span class=special>&lt;[</span><i>(tag)</i><span class=special>[,</span><i>(key extractor)</i><span class=special>[,</span><i>(comparison predicate)</i><span class=special>]]]&gt;</span>
<span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)</span>
<span class=special>&lt;[</span><i>(key extractor)</i><span class=special>[,</span><i>(comparison predicate)</i><span class=special>]]&gt;</span>
</pre></blockquote>
<h3><a name="rnk_ops">Rank operations</a></h3>
<p>
Besides <code>nth</code> and <code>rank</code>, ranked indices provide member functions
<ul>
<li><code>find_rank</code>,</li>
<li><code>lower_bound_rank</code>,</li>
<li><code>upper_bound_rank</code>,</li>
<li><code>equal_range_rank</code> and </li>
<li><code>range_rank</code></li>
</ul>
that behave as their normal
<a href="basics.html#special_lookup">lookup</a> and <a href="basics.html#range">range retrieval</a>
counterparts (<code>find</code>, <code>lower_bound</code> etc.) but return ranks rather than iterators.
</p>
<blockquote><pre>
<span class=keyword>void</span> <span class=identifier>percentile</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=identifier>int_multiset</span><span class=special>&amp;</span> <span class=identifier>s</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>&lt;&lt;</span><span class=identifier>n</span><span class=special>&lt;&lt;</span><span class=string>&quot; lies in the &quot;</span><span class=special>&lt;&lt;</span>
<span class=identifier>s</span><span class=special>.</span><span class=identifier>upper_bound_rank</span><span class=special>(</span><span class=identifier>n</span><span class=special>)*</span><span class=number>100.0</span><span class=special>/</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</span><span class=special>()&lt;&lt;</span><span class=string>&quot; percentile\n&quot;</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
You might think that <code>upper_bound_rank(n)</code> is mere shorthand for
<code>rank(upper_bound(n))</code>: in reality, though, you should prefer using
<code>*_rank</code> operations directly as they run faster than the
alternative formulations.
</p>
<h2><a name="hashed_indices">Hashed indices</a></h2>
<p>
Hashed indices constitute a trade-off with respect to ordered indices: if correctly used,
they provide much faster lookup of elements, at the expense of losing sorting
information.
Let us revisit our <code>employee_set</code> example: suppose a field for storing
the Social Security number is added, with the requisite that lookup by this
number should be as fast as possible. Instead of the usual ordered index, a
hashed index can be resorted to:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>hashed_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>member</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>employee</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>id</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>int</span> <span class=identifier>ssnumber</span><span class=special>;</span>
<span class=identifier>employee</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>id</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>&amp;</span> <span class=identifier>name</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>ssnumber</span><span class=special>):</span>
<span class=identifier>id</span><span class=special>(</span><span class=identifier>id</span><span class=special>),</span><span class=identifier>name</span><span class=special>(</span><span class=identifier>name</span><span class=special>),</span><span class=identifier>ssnumber</span><span class=special>(</span><span class=identifier>ssnumber</span><span class=special>){}</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&lt;(</span><span class=keyword>const</span> <span class=identifier>employee</span><span class=special>&amp;</span> <span class=identifier>e</span><span class=special>)</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>id</span><span class=special>&lt;</span><span class=identifier>e</span><span class=special>.</span><span class=identifier>id</span><span class=special>;}</span>
<span class=special>};</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=comment>// sort by employee::operator&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=comment>// sort by less&lt;string&gt; on name</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=comment>// hashed on ssnumber</span>
<span class=identifier>hashed_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span>
</pre></blockquote>
<p>
Note that the hashed index does not guarantee any particular ordering of the
elements: so, for instance, we cannot efficiently query the employees whose SSN is
greater than a given number. Usually, you must consider these restrictions when
determining whether a hashed index is preferred over an ordered one.
</p>
<p>
Hashed indices replicate the interface of <code>std::unordered_set</code> and
<code>std::unordered_multiset</code>, with only minor differences where required
by the general constraints of <code>multi_index_container</code>s, and provide
additional useful capabilities like in-place updating of elements.
Check the <a href="../reference/hash_indices.html">reference</a> for a
complete specification of the interface of hashed indices,
and <a href="../examples.html#example8">example 8</a> and
<a href="../examples.html#example9">example 9</a> for practical applications.
</p>
</p>
<h3><a name="hash_unique_non_unique">Unique and non-unique variants</a></h3>
<p>
Just like ordered indices, hashed indices have unique and non-unique variants, selected
with the specifiers <code>hashed_unique</code> and <code>hashed_non_unique</code>,
respectively. In the latter case, elements with equivalent keys are kept together and can
be jointly retrieved by means of the <code>equal_range</code> member function.
</p>
<h3><a name="hash_spec">Specification</a></h3>
<p>
Hashed indices specifiers have two alternative syntaxes, depending on whether
<a href="basics.html#tagging">tags</a> are provided or not:
</p>
<blockquote><pre>
<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>&lt;[</span><i>(tag)</i><span class=special>[,</span><i>(key extractor)</i><span class=special>[,</span><i>(hash function)</i><span class=special>[,</span><i>(equality predicate)</i><span class=special>]]]]&gt;</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>&lt;[</span><i>(key extractor)</i><span class=special>[,</span><i>(hash function)</i><span class=special>[,</span><i>(equality predicate)</i><span class=special>]]]&gt;</span>
</pre></blockquote>
<p>
The key extractor parameter works in exactly the same way as for
<a href="basics.html#key_extraction">ordered indices</a>; lookup, insertion,
etc., are based on the key returned by the extractor rather than the whole
element.
</p>
<p>
The hash function is the very core of the fast lookup capabilities of this type of
indices: a hasher is just a unary function object
returning an <code>std::size_t</code> value for any given
key. In general, it is impossible that every key map to a different hash value, for
the space of keys can be greater than the number of permissible hash codes: what
makes for a good hasher is that the probability of a collision (two different
keys with the same hash value) is as close to zero as possible. This is a statistical
property depending on the typical distribution of keys in a given application, so
it is not feasible to have a general-purpose hash function with excellent results
in <i>every</i> possible scenario; the default value for this parameter uses
<a href="../../../functional/hash/index.html">Boost.Hash</a>, which often provides good
enough results.
</p>
<p>
The equality predicate is used to determine whether two keys are to be treated
as the same. The default
value <code>std::equal_to&lt;KeyFromValue::result_type&gt;</code> is in most
cases exactly what is needed, so very rarely will you have to provide
your own predicate. Note that hashed indices require that two
equivalent keys have the same hash value, which
in practice greatly reduces the freedom in choosing an equality predicate.
</p>
<h3><a name="hash_lookup">Lookup</a></h3>
<p>
The lookup interface of hashed indices consists in member functions
<code>find</code>, <code>count</code>, <code>contains</code> and <code>equal_range</code>.
Note that <code>lower_bound</code> and <code>upper_bound</code> are not
provided, as there is no intrinsic ordering of keys in this type of indices.
</p>
<p>
Just as with ordered indices, these member functions take keys
as their search arguments, rather than entire objects. Remember that
ordered indices lookup operations are further augmented to accept
<i>compatible keys</i>, which can roughly be regarded as "subkeys".
For hashed indices, a concept of
<a href="../reference/hash_indices.html#lookup">compatible key</a> is also
supported, though its usefulness is much more limited: basically,
a compatible key is an object which is entirely equivalent to
a native object of <code>key_type</code> value, though maybe with
a different internal representation:
</p>
<blockquote><pre>
<span class=comment>// US SSN numbering scheme</span>
<span class=keyword>struct</span> <span class=identifier>ssn</span>
<span class=special>{</span>
<span class=identifier>ssn</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>area_no</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>group_no</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>serial_no</span><span class=special>):</span>
<span class=identifier>area_no</span><span class=special>(</span><span class=identifier>area_no</span><span class=special>),</span><span class=identifier>group_no</span><span class=special>(</span><span class=identifier>group_no</span><span class=special>),</span><span class=identifier>serial_no</span><span class=special>(</span><span class=identifier>serial_no</span><span class=special>)</span>
<span class=special>{}</span>
<span class=keyword>int</span> <span class=identifier>to_int</span><span class=special>()</span><span class=keyword>const</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>serial_no</span><span class=special>+</span><span class=number>10000</span><span class=special>*</span><span class=identifier>group_no</span><span class=special>+</span><span class=number>1000000</span><span class=special>*</span><span class=identifier>area_no</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>private</span><span class=special>:</span>
<span class=keyword>int</span> <span class=identifier>area_no</span><span class=special>;</span>
<span class=keyword>int</span> <span class=identifier>group_no</span><span class=special>;</span>
<span class=keyword>int</span> <span class=identifier>serial_no</span><span class=special>;</span>
<span class=special>};</span>
<span class=comment>// interoperability with SSNs in raw int form</span>
<span class=keyword>struct</span> <span class=identifier>ssn_equal</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>ssn</span><span class=special>&amp;</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=keyword>const</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>to_int</span><span class=special>()==</span><span class=identifier>y</span><span class=special>;</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=identifier>ssn</span><span class=special>&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>==</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>to_int</span><span class=special>();</span>
<span class=special>}</span>
<span class=special>};</span>
<span class=keyword>struct</span> <span class=identifier>ssn_hash</span>
<span class=special>{</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ssn</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;()(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>to_int</span><span class=special>());</span>
<span class=special>}</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>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>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;()(</span><span class=identifier>x</span><span class=special>);</span>
<span class=special>}</span>
<span class=special>};</span>
<span class=keyword>typedef</span> <span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>2</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>employee_set_by_ssn</span><span class=special>;</span>
<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
<span class=identifier>employee_set_by_ssn</span><span class=special>&amp;</span> <span class=identifier>ssn_index</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special>&lt;</span><span class=number>2</span><span class=special>&gt;();</span>
<span class=special>...</span>
<span class=comment>// find an employee by ssn</span>
<span class=identifier>employee</span> <span class=identifier>e</span><span class=special>=*(</span><span class=identifier>ssn_index</span><span class=special>.</span><span class=identifier>find</span><span class=special>(</span><span class=identifier>ssn</span><span class=special>(</span><span class=number>12</span><span class=special>,</span><span class=number>1005</span><span class=special>,</span><span class=number>20678</span><span class=special>),</span><span class=identifier>ssn_hash</span><span class=special>(),</span><span class=identifier>ssn_equal</span><span class=special>()));</span>
</pre></blockquote>
<p>
In the example, we provided a hash functor <code>ssn_hash</code> and an
equality predicate <code>ssn_equal</code> allowing for interoperability
between <code>ssn</code> objects and the raw <code>int</code>s stored as
<code>SSN</code>s in <code>employee_set</code>.
</p>
<p>
By far, the most useful application of compatible keys in the context
of hashed indices lies in the fact that they allow for seamless usage of
<a href="key_extraction.html#composite_keys">composite keys</a>.
</p>
<h3><a name="hash_updating">Updating</a></h3>
<p>
Hashed indices have
<a href="../reference/hash_indices.html#replace"><code>replace</code></a>,
<a href="../reference/hash_indices.html#modify"><code>modify</code></a> and
<a href="../reference/hash_indices.html#modify_key"><code>modify_key</code></a>
member functions, with the same functionality as in ordered indices.
</p>
<h3><a name="guarantees">Guarantees on iterator validity and exception safety</a></h3>
<p>
Due to the internal constraints imposed by the Boost.MultiIndex framework,
hashed indices provide guarantees on iterator validity and
exception safety that are actually stronger than required by the
C++ standard with respect to unordered associative containers:
<ul>
<li>Iterator validity is preserved in any case during insertion or rehashing:
C++ unordered associative containers can invalidate iterators when a rehash (implicit or explicit)
is performed.</li>
<li>Erasing an element or range of elements via iterators does not throw ever,
as the internal hash function and equality predicate objects are not actually
invoked.</li>
<li><code>rehash</code> provides the strong exception safety guarantee
unconditionally. The standard only warrants it for unordered associative containers if the internal hash function and
equality predicate objects do not throw. The somewhat surprising consequence
is that a standard-compliant <code>std::unordered_set</code> might erase
elements if an exception is thrown during rehashing!</li>
</ul>
In general, these stronger guarantees play in favor of the user's convenience,
specially that which refers to iterator stability. A (hopefully minimal)
degradation in performance might result in exchange for these commodities,
though.
</p>
<h2><a name="rnd_indices">Random access indices</a></h2>
<p>
Random access indices offer the same kind of functionality as
<a href="basics.html#seq_indices">sequenced indices</a>, with the extra advantages
that their iterators are random access, and <code>operator[]</code>
and <code>at()</code> are provided for accessing
elements based on their position in the index. Let us rewrite a
container used in a previous <a href="basics.html#list_fast_lookup">example</a>,
using random access instead of sequenced indices:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>random_access_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=comment>// text container with fast lookup based on a random access index</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>random_access</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>text_container</span><span class=special>;</span>
<span class=comment>// global text container object</span>
<span class=identifier>text_container</span> <span class=identifier>tc</span><span class=special>;</span>
</pre></blockquote>
<p>
Random access capabilities allow us to efficiently write code
like the following:
</p>
<blockquote><pre>
<span class=keyword>void</span> <span class=identifier>print_page</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>page_num</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>static</span> <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>words_per_page</span><span class=special>=</span><span class=number>50</span><span class=special>;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>pos0</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>min</span><span class=special>(</span><span class=identifier>tc</span><span class=special>.</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>page_num</span><span class=special>*</span><span class=identifier>words_per_page</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>pos1</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>min</span><span class=special>(</span><span class=identifier>tc</span><span class=special>.</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>pos0</span><span class=special>+</span><span class=identifier>words_per_page</span><span class=special>);</span>
<span class=comment>// note random access iterators can be added offsets</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>copy</span><span class=special>(</span>
<span class=identifier>tc</span><span class=special>.</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>pos0</span><span class=special>,</span><span class=identifier>tc</span><span class=special>.</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>pos1</span><span class=special>,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream_iterator</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>));</span>
<span class=special>}</span>
<span class=keyword>void</span> <span class=identifier>print_random_word</span><span class=special>()</span>
<span class=special>{</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>&lt;&lt;</span><span class=identifier>tc</span><span class=special>[</span><span class=identifier>rand</span><span class=special>()%</span><span class=identifier>tc</span><span class=special>.</span><span class=identifier>size</span><span class=special>()];</span>
<span class=special>}</span>
</pre></blockquote>
<p>
This added flexibility comes at a price: insertions and deletions at positions
other than the end of the index have linear complexity, whereas these operations
are constant time for sequenced indices. This situation is reminiscent of the
differences in complexity behavior between <code>std::list</code> and
<code>std::vector</code>: in the case of random access indices, however,
insertions and deletions never incur any element copying, so the actual
performance of these operations can be acceptable, despite the theoretical
disadvantage with respect to sequenced indices.
</p>
<p>
<a href="../examples.html#example10">Example 10</a> and
<a href="../examples.html#example11">example 11</a> in the examples section put
random access indices in practice.
</p>
<h3><a name="rnd_spec">Specification</a></h3>
<p>
Random access indices are specified with the <code>random_access</code> construct,
where the <a href="basics.html#tagging">tag</a> parameter is, as usual, optional:
</p>
<blockquote><pre>
<span class=identifier>random_access</span><span class=special>&lt;[</span><i>(tag)</i><span class=special>]&gt;</span>
</pre></blockquote>
<h3><a name="rnd_interface">Interface</a></h3>
<p>
All public functions offered by sequenced indices are also provided
by random access indices, so that the latter can act as a drop-in replacement
of the former (save with respect to their complexity bounds, as explained above).
Besides, random access
indices have <code>operator[]</code> and <code>at()</code> for positional
access to the elements, and member functions
<a href="../reference/rnd_indices.html#capacity_memfun"><code>capacity</code></a> and
<a href="../reference/rnd_indices.html#reserve"><code>reserve</code></a>
that control internal reallocation in a similar manner as the homonym
facilities in <code>std::vector</code>. Check the
<a href="../reference/rnd_indices.html">reference</a> for details.
</p>
<h3><a name="rnd_vs_vector">Comparison with <code>std::vector</code></a></h3>
<p>
It is tempting to see random access indices as an analogue of <code>std::vector</code>
for use in Boost.MultiIndex, but this metaphor can be misleading, as both constructs,
though similar in many respects, show important semantic differences. An
advantage of random access indices is that their iterators, as well as references
to their elements, are <i>stable</i>, that is, they remain valid after any insertions
or deletions. On the other hand, random access indices have several disadvantages with
respect to <code>std::vector</code>s:
<ul>
<li>They do not provide <i>memory contiguity</i>, a property
of <code>std::vector</code>s by which elements are stored adjacent to one
another in a single block of memory.
</li>
<li>As usual in Boost.MultiIndex, elements of random access indices are immutable
and can only be modified through member functions
<a href="../reference/rnd_indices.html#replace"><code>replace</code></a> and
<a href="../reference/rnd_indices.html#modify"><code>modify</code></a>.
This precludes the usage of many mutating
algorithms that are nonetheless applicable to <code>std::vector</code>s.
</li>
</ul>
The latter shortcoming can be partially remedied by means of the
<a href="#rearrange">rearranging interface</a> these indices provide.
</p>
<p>
In general, it is more instructive to regard random access indices as
a variation of sequenced indices providing random access semantics, instead
of insisting on the <code>std::vector</code> analogy.
</p>
<h2><a name="rearrange">Index rearranging</a></h2>
<p>
By design, index elements are immutable, i.e. iterators only grant
<code>const</code> access to them, and only through the provided
updating interface (<code>replace</code>, <code>modify</code> and
<code>modify_key</code>) can the elements be modified. This restriction
is set up so that the internal invariants of key-based indices are
not broken (for instance, ascending order traversal in ordered
indices), but induces important limitations in non key-based indices:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>random_access</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>container</span><span class=special>;</span>
<span class=identifier>container</span> <span class=identifier>c</span><span class=special>;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>mt19937</span> <span class=identifier>rng</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// compiler error: assignment to read-only objects</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>shuffle</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><span class=identifier>rng</span><span class=special>);</span>
</pre></blockquote>
<p>
What is unfortunate about the previous example is that the operation
performed by <code>std::shuffle</code> is potentially compatible
with <code>multi_index_container</code> invariants, as its result can be
described by a permutation of the elements in the random access index
with no actual modifications to the elements themselves. There are many
more examples of such compatible algorithms in the C++ standard library,
like for instance all sorting and partition functions.
</p>
<p>
Sequenced and random access indices provide a means to take advantage
of such external algorithms. In order to introduce this facility we need
a preliminary concept: a <i>view</i> of an index is defined as
some iterator range [<code>first</code>,<code>last</code>) over the
elements of the index such that all its elements are contained in the
range exactly once. Continuing with our example, we can apply
<code>std::shuffle</code> on an ad hoc view obtained from the
container:
</p>
<blockquote><pre>
<span class=comment>// note that the elements of the view are not copies of the elements
// in c, but references to them</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>v</span><span class=special>;</span>
<span class=identifier>BOOST_FOREACH</span><span class=special>(</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&amp;</span> <span class=identifier>i</span><span class=special>,</span><span class=identifier>c</span><span class=special>)</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>push_back</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>cref</span><span class=special>(</span><span class=identifier>i</span><span class=special>));</span>
<span class=comment>// this compiles OK, as reference_wrappers are swappable</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>shuffle</span><span class=special>(</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>rng</span><span class=special>);</span>
</pre></blockquote>
<p>
Elements of <code>v</code> are <code>reference_wrapper</code>s (from
<a href="../../../../doc/html/ref.html">Boost.Ref</a>) to the actual elements
in the multi-index container. These objects still do not allow modification
of the referenced entities, but they are swappable,
which is the only requirement <code>std::shuffle</code> imposes. Once
we have our desired rearrange stored in the view, we can transfer it to
the container with
</p>
<blockquote><pre>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>());</span>
</pre></blockquote>
<p>
<code>rearrange</code> accepts an input iterator signaling the beginning
of the external view (and end iterator is not needed since the length of
the view is the same as that of the index) and internally relocates the
elements of the index so that their traversal order matches the view.
Albeit with some circumventions, <code>rearrange</code> allows for the
application of a varied range of algorithms to non key-based indices.
Please note that the view concept is very general, and in no way tied
to the particular implementation example shown above. For instance, indices
of a <code>multi_index_container</code> are indeed views with respect to
its non key-based indices:
</p>
<blockquote><pre>
<span class=comment>// rearrange as index #1 (ascending order)</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>get</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;().</span><span class=identifier>begin</span><span class=special>());</span>
<span class=comment>// rearrange in descending order</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>get</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;().</span><span class=identifier>rbegin</span><span class=special>());</span>
</pre></blockquote>
<p>
The only important requirement imposed on views is that they must be
<i>free</i>, i.e. they are not affected by relocations on the base index:
thus, <code>rearrange</code> does not accept the following:
</p>
<blockquote><pre>
<span class=comment>// undefined behavior: [rbegin(),rend()) is not free with respect
// to the base index</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>rbegin</span><span class=special>());</span>
</pre></blockquote>
<p>
The view concept is defined in detail in the
<a href="../reference/indices.html#views">reference</a>.
See <a href="../examples.html#example11">example 11</a> in the examples section
for a demonstration of use of <code>rearrange</code>.
</p>
<h2><a name="iterator_to"><code>iterator_to</code></a></h2>
<p>
All indices of Boost.MultiIndex provide a member function called <code>iterator_to</code>
which returns an iterator to a given element of the container:
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>c</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// convoluted way to do c.pop_back()</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>iterator_to</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>back</span><span class=special>()));</span>
<span class=comment>// The following, though similar to the previous code,
// does not work: iterator_to accepts a reference to
// the element in the container, not a copy.</span>
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>back</span><span class=special>();</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>iterator_to</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// run-time failure ensues</span>
</pre></blockquote>
<p>
<code>iterator_to</code> provides a way to retrieve an iterator to an element
from a pointer to the element, thus making iterators and pointers interchangeable
for the purposes of element pointing (not so for traversal) in many situations.
This notwithstanding, it is not the aim of <code>iterator_to</code> to
promote the usage of pointers as substitutes for real iterators: the latter are
specifically designed for handling the elements of a container,
and not only benefit from the iterator orientation of container interfaces,
but are also capable of exposing many more programming bugs than raw pointers, both
at compile and run time. <code>iterator_to</code> is thus meant to be used
in scenarios where access via iterators is not suitable or desirable:
<ul>
<li>Interoperability with preexisting APIs based on pointers or references.</li>
<li>Publication of pointer-based interfaces (for instance, when
designing a C-compatible library).
</li>
<li>The exposure of pointers in place of iterators can act as a <i>type
erasure</i> barrier effectively decoupling the user of the code
from the implementation detail of which particular container is being
used. Similar techniques, like the famous Pimpl idiom, are used
in large projects to reduce dependencies and build times.
</li>
<li>Self-referencing contexts where an element acts upon its owner
container and no iterator to itself is available.
</li>
</ul>
</p>
<h2><a name="node_handling">Node handling operations</a></h2>
<p>
Using direct node manipulation, elements can be passed between
<code>multi_index_container</code>s without actually copying them:
</p>
<blockquote><pre>
<span class=comment>// move an employee to the retiree archive</span>
<span class=keyword>void</span> <span class=identifier>move_to_retirement</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>ssnumber</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>es</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>archive</span><span class=special>)</span>
<span class=special>{</span>
<span class=comment>// assume employee_set has an index on SS number(not shown before)</span>
<span class=comment>// extract the employee with given SS number to a node handle</span>
<span class=identifier>employee_set_by_ssn</span><span class=special>::</span><span class=identifier>node_type</span> <span class=identifier>node</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special>&lt;</span><span class=identifier>ssn</span><span class=special>&gt;().</span><span class=identifier>extract</span><span class=special>(</span><span class=identifier>ssnumber</span><span class=special>);</span>
<span class=keyword>if</span><span class=special>(!</span><span class=identifier>node</span><span class=special>.</span><span class=identifier>empty</span><span class=special>()){</span> <span class=comment>// employee found
// re-insert into archive (note the use of std::move)</span>
<span class=identifier>archive</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>move</span><span class=special>(</span><span class=identifier>node</span><span class=special>));</span>
<span class=special>}</span>
<span class=special>}</span>
</pre></blockquote>
<p>
In the example, the internal node is transferred as-is from <code>es</code> to <code>archive</code>,
which is more efficient than erasing from the source and recreating in destination.
<code>node_type</code> is a move-only class used to pass nodes around, and its interface follows
that of the <a href="https://en.cppreference.com/w/cpp/container/node_handle">homonym type</a>
for C++ associative containers (set containers version). Boost.MultiIndex provides node extraction
and insertion operations for all index types, including sequenced ones (by contrast,
<code>std::list</code> does not have such features):
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>src</span><span class=special>;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>dst</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// transfer even numbers from src to dst</span>
<span class=keyword>for</span><span class=special>(</span><span class=keyword>auto</span> <span class=identifier>first</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>last</span><span class=special>=</span><span class=identifier>src</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>
<span class=keyword>if</span><span class=special>(*</span><span class=identifier>first</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=identifier>dst</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>dst</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>extract</span><span class=special>(</span><span class=identifier>first</span><span class=special>++));</span>
<span class=keyword>else</span> <span class=special>++</span><span class=identifier>first</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
Note that <code>src</code> and <code>dst</code> are of different types,
yet transfer is possible. Two <code>multi_index_container</code>s are
node-compatible (that is, they use the same <code>node_type</code>) if
they have the same element and allocator types and their respective indices match
one by one without regard to whether they are unique or non-unique or to
their particular configuration parameters: they are both ordered, or
both sequenced, etc.
</p>
<p>
Alternatively, direct node transfer between two containers can be done without
keeping intervening <code>node_type</code>s thanks to <code>merge</code> (key-based
indices) and <code>splice</code> (non key-based indices).
</p>
<blockquote><pre>
<span class=comment>// move older employees to retirement</span>
<span class=keyword>void</span> <span class=identifier>move_to_retirement_by_age</span><span class=special>(
</span><span class=keyword>int</span> <span class=identifier>max_age</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>es</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>archive</span><span class=special>)</span>
<span class=special>{</span>
<span class=comment>// assume employee_set has an index on age (not shown before)</span>
<span class=identifier>employee_set_by_age</span><span class=special>&amp;</span> <span class=identifier>ea</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special>&lt;</span><span class=identifier>age</span><span class=special>&gt;();</span>
<span class=comment>// archive employees with age&gt;max_age</span>
<span class=identifier>archive</span><span class=special>.</span><span class=identifier>merge</span><span class=special>(</span><span class=identifier>ea</span><span class=special>,</span><span class=identifier>ea</span><span class=special>.</span><span class=identifier>upper_bound</span><span class=special>(</span><span class=identifier>max_age</span><span class=special>),</span><span class=identifier>ea</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
<span class=special>}</span>
<span class=special>...</span>
<span class=comment>// transfer even numbers from src to dst</span>
<span class=keyword>for</span><span class=special>(</span><span class=keyword>auto</span> <span class=identifier>first</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>last</span><span class=special>=</span><span class=identifier>src</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>
<span class=keyword>if</span><span class=special>(*</span><span class=identifier>first</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=identifier>dst</span><span class=special>.</span><span class=identifier>splice</span><span class=special>(</span><span class=identifier>dst</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>src</span><span class=special>,</span><span class=identifier>first</span><span class=special>++);</span>
<span class=keyword>else</span> <span class=special>++</span><span class=identifier>first</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
There are overloads of <code>merge</code>/<code>splice</code> for transferring a single element,
a range between two iterators and an entire container: for further details, consult
for instance the reference for <a href="../reference/ord_indices.html#merge">ordered indices</a> and for
<a href="../reference/seq_indices.html#splice">sequenced indices</a>
(the rest of indices provide one interface or the other).
Please note that sequenced and random access indices do also have an operation called <code>merge</code>,
but this follows the specification of <code>std::list::merge</code>, which has a somewhat
different behavior (source and destination are required to be ordered by the same criterion). This is
a rather confusing naming issue that Boost.MultiIndex simply inherits from the C++ standard.
</p>
<h2><a name="ordered_node_compression">Ordered indices node compression</a></h2>
<p>
Ordered and ranked indices are implemented by means of a data structure
known as a <i>red-black tree</i>. Nodes of a red-back tree contain pointers
to the parent and the two children nodes, plus a 1-bit field referred to as
the <i>node color</i> (hence the name of the structure). Due to alignment
issues, on most architectures the color field occupies one entire word, that is,
4 bytes in 32-bit systems and 8 bytes in 64-bit environments. This waste
of space can be avoided by embedding the color bit inside one of the
node pointers, provided not all the bits of the pointer representation contain
useful information: this is precisely the case in many architectures where
such nodes are aligned to even addresses, which implies that the least
significant bit of the address must always be zero.
</p>
<p>
Boost.MultiIndex ordered and ranked indices implement this type of node compression
whenever applicable. As compared with common implementations of the STL
container <code>std::set</code>, node compression can
result in a reduction of header overload by 25% (from 16 to 12 bytes on
typical 32-bit architectures, and from 32 to 24 bytes on 64-bit systems).
The impact on performance of this optimization has been checked to be negligible
for moderately sized containers, whereas containers with many elements (hundreds
of thousands or more) perform faster with this optimization, most likely due to
L1 and L2 cache effects.
</p>
<p>
Node compression can be disabled by globally setting the macro
<code>BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES</code>.
</p>
<hr>
<div class="prev_link"><a href="basics.html"><img src="../prev.gif" alt="basics" border="0"><br>
Basics
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="key_extraction.html"><img src="../next.gif" alt="key estraction" border="0"><br>
Key extraction
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised August 16th 2021</p>
<p>&copy; Copyright 2003-2021 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

+409
View File
@@ -0,0 +1,409 @@
<!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 - Tutorial - Techniques</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<link rel="start" href="../index.html">
<link rel="prev" href="debug.html">
<link rel="up" href="index.html">
<link rel="next" href="../reference/index.html">
</head>
<body>
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Techniques</h1>
<div class="prev_link"><a href="debug.html"><img src="../prev.gif" alt="debugging support" border="0"><br>
Debugging support
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="../reference/index.html"><img src="../next.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
</a></div><br clear="all" style="clear: all;">
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#emulate_std_containers">Emulating standard containers with
<code>multi_index_container</code></a>
<ul>
<li><a href="#emulate_assoc_containers">Emulation of associative
containers</a></li>
<li><a href="#emulate_std_list">Emulation of <code>std::list</code></a></li>
</ul>
</li>
<li><a href="#metaprogrammming">Metaprogramming and <code>multi_index_container</code></a>
<ul>
<li><a href="#analysis">Analysis</a></li>
<li><a href="#synthesis">Synthesis</a></li>
</ul>
</li>
</ul>
<h2><a name="emulate_std_containers">Emulating standard containers with
<code>multi_index_container</code></a></h2>
<h3><a name="emulate_assoc_containers">Emulation of associative
containers</a></h3>
<p>
Academic motivations aside, there is a practical interest in emulating standard
associative containers by means of <code>multi_index_container</code>, namely to take
advantage of extended functionalities provided by <code>multi_index_container</code> for
lookup, range querying and updating.
</p>
<p>
In order to emulate a <code>std::set</code> one can follow the substitution
rule:
</p>
<blockquote><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>Key</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>&gt;,</span><span class=identifier>Compare</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>Allocator</span>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
In the default case where <code>Compare=std::less&lt;Key></code> and
<code>Allocator=std::allocator&lt;Key></code>, the substitution rule is
simplified as
</p>
<blockquote><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>&gt;</span> <span class=special>-&gt;</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
The substitution of <code>multi_index_container</code> for <code>std::set</code> keeps
the whole set of functionality provided by <code>std::set</code>, so in
principle it is a drop-in replacement needing no further adjustments.
</p>
<p>
<code>std::multiset</code> can be emulated in a similar manner, according to the
following rule:
</p>
<blockquote><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>Key</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>&gt;,</span><span class=identifier>Compare</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>Allocator</span>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
When default values are taken into consideration, the rule takes the form
</p>
<blockquote><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>Key</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
The emulation of <code>std::multiset</code>s with <code>multi_index_container</code>
results in a slight difference with respect to the interface offered: the member
function <code>insert(const value_type&amp;)</code> does not return an
<code>iterator</code> as in <code>std::multiset</code>s, but rather a
<code>std::pair&lt;iterator,bool></code> in the spirit of <code>std::set</code>s.
In this particular case, however, the <code>bool</code> member of the returned
pair is always <code>true</code>.
</p>
<p>
The case of <code>std::map</code>s and <code>std::multimap</code>s does not lend
itself to such a direct emulation by means of <code>multi_index_container</code>. The main
problem lies in the fact that elements of a <code>multi_index_container</code> are treated
as constant, while the <code>std::map</code> and <code>std::multimap</code> handle
objects of type <code>std::pair&lt;const Key,T></code>, thus allowing for free
modification of the value part. To overcome this difficulty we need to create an ad
hoc pair class:
</p>
<blockquote><pre>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>T1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>T2</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>mutable_pair</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>T1</span> <span class=identifier>first_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>T2</span> <span class=identifier>second_type</span><span class=special>;</span>
<span class=identifier>mutable_pair</span><span class=special>():</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>T1</span><span class=special>()),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>T2</span><span class=special>()){}</span>
<span class=identifier>mutable_pair</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>T1</span><span class=special>&amp;</span> <span class=identifier>f</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>T2</span><span class=special>&amp;</span> <span class=identifier>s</span><span class=special>):</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>f</span><span class=special>),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>s</span><span class=special>){}</span>
<span class=identifier>mutable_pair</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>T1</span><span class=special>,</span><span class=identifier>T2</span><span class=special>&gt;&amp;</span> <span class=identifier>p</span><span class=special>):</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>first</span><span class=special>),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>second</span><span class=special>){}</span>
<span class=identifier>T1</span> <span class=identifier>first</span><span class=special>;</span>
<span class=keyword>mutable</span> <span class=identifier>T2</span> <span class=identifier>second</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
and so the substitution rules are:
</p>
<blockquote><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>map</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>Element</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&amp;</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>&gt;,</span><span class=identifier>Compare</span><span class=special>&gt;</span>
<span class=special>&gt;,</span>
<span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special>&lt;</span><span class=identifier>Element</span><span class=special>&gt;::</span><span class=identifier>other</span>
<span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>multimap</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>Element</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&amp;</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>&gt;,</span><span class=identifier>Compare</span><span class=special>&gt;</span>
<span class=special>&gt;,</span>
<span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special>&lt;</span><span class=identifier>Element</span><span class=special>&gt;::</span><span class=identifier>other</span>
<span class=special>&gt;</span>
(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_pair</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>&gt;</span>)
</pre></blockquote>
<p>
If default values are considered, the rules take the form:
</p>
<blockquote><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>map</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>Element</span><span class=special>,
</span><span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&amp;</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>multimap</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>Element</span><span class=special>,
</span><span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&amp;</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_pair</span><span class=special>&lt;</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>&gt;</span>)
</pre></blockquote>
<p>
Unlike as with standard sets, the interface of these <code>multi_index_container</code>-emulated
maps does not exactly conform to that of <code>std::map</code>s and
<code>std::multimap</code>s. The most obvious difference is the lack of
<code>operator []</code>, either in read or write mode; this, however, can be
emulated with appropriate use of <code>find</code> and <code>insert</code>.
</p>
<p>
These emulations of standard associative containers with <code>multi_index_container</code>
are comparable to the original constructs in terms of space and time efficiency.
See the <a href="../performance.html">performance section</a> for further details.
</p>
<h3><a name="emulate_std_list">Emulation of <code>std::list</code></a></h3>
<p>
Unlike the case of associative containers, emulating <code>std::list</code>
in Boost.MultiIndex does not add any significant functionality, so the following
is presented merely for completeness sake.
</p>
<p>
Much as with standard maps, the main difficulty to overcome when emulating
<code>std::list</code> derives from the constant nature of elements of a
<code>multi_index_container</code>. Again, some sort of adaption class is needed, like
for instance the following:
</p>
<blockquote><pre>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>T</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>mutable_value</span>
<span class=special>{</span>
<span class=identifier>mutable_value</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>T</span><span class=special>&amp;</span> <span class=identifier>t</span><span class=special>):</span><span class=identifier>t</span><span class=special>(</span><span class=identifier>t</span><span class=special>){}</span>
<span class=keyword>operator</span> <span class=identifier>T</span><span class=special>&amp;()</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>t</span><span class=special>;}</span>
<span class=keyword>private</span><span class=special>:</span>
<span class=keyword>mutable</span> <span class=identifier>T</span> <span class=identifier>t</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
which allows us to use the substitution rule:
</p>
<blockquote><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>Element</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;,</span>
<span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special>&lt;</span><span class=identifier>Element</span><span class=special>&gt;::</span><span class=identifier>other</span>
<span class=special>&gt;</span>
(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_value</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span>)
</pre></blockquote>
<p>
or, if the default value <code>Allocator=std::allocator&lt;T></code> is used:
</p>
<blockquote><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>-&gt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>mutable_value</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;,</span><span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span> <span class=special>&gt;</span>
</pre></blockquote>
<h2><a name="metaprogrammming">Metaprogramming and <code>multi_index_container</code></a></h2>
<p>
Boost.MultiIndex provides a number of facilities intended to allow the analysis and
synthesis of <code>multi_index_container</code> instantiations with metaprogramming.
</p>
<h3><a name="analysis">Analysis</a></h3>
<p>
Given a <code>multi_index_container</code> instantiation, the following nested types are
provided for compile-time inspection of the various types occurring in the
definition of the <code>multi_index_container</code>:
<ul>
<li><code>index_specifier_type_list</code>,</li>
<li><code>index_type_list</code>,</li>
<li><code>iterator_type_list</code>,</li>
<li><code>const_iterator_type_list</code>.</li>
</ul>
Each of these types is an
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</a>
with as many elements as indices
comprise the <code>multi_index_container</code>: for instance, the <code>n</code>-th
element of <code>iterator_type_list</code> is the same as
<code>nth_index&lt;n>::type::iterator</code>. Boost.Mp11 makes it very easy
to inspect and manipulate these lists:
</p>
<blockquote><pre>
<span class=keyword>using</span> <span class=identifier>indexed_t</span><span class=special>=</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;;</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>mp11</span><span class=special>::</span><span class=identifier>mp_for_each</span><span class=special>&lt;</span><span class=identifier>indexed_t</span><span class=special>::</span><span class=identifier>index_specifier_type_list</span><span class=special>&gt;([](</span><span class=keyword>auto</span> <span class=identifier>I</span><span class=special>){</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span> <span class=special>&lt;&lt;</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>typeindex</span><span class=special>::</span><span class=identifier>type_id</span><span class=special>&lt;</span><span class=identifier>decltype</span><span class=special>(</span><span class=identifier>I</span><span class=special>)&gt;().</span><span class=identifier>pretty_name</span><span class=special>()</span> <span class=special>&lt;&lt;</span> <span class=string>&quot;\n&quot;</span><span class=special>;</span>
<span class=special>});</span>
<span class=comment>// Output:
//
// struct boost::multi_index::ordered_unique&lt;struct boost::multi_index::identity&lt;int&gt;,void,void&gt;
// struct boost::multi_index::sequenced&lt;struct boost::multi_index::tag&lt;&gt; &gt;</span>
</pre></blockquote>
<p>
A subtle but important distinction exists between
<code>index_specifier_type_list</code> and <code>index_type_list</code>:
the former list holds the index <i>specifiers</i>
with which the <code>multi_index_container</code> instantiation was defined,
while the latter gives access to the actual implementation classes
corresponding to each specifier. In the example above,
<code>indexed_t::index_specifier_type_list</code> is a type list with
elements
</p>
<blockquote><pre>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span><span class=special>&gt;</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;</span>
</pre></blockquote>
<p>
while <code>indexed_t::index_type_list</code> holds the types
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>::</span><span class=identifier>nth_type</span><span class=special>&lt;</span><span class=number>0</span><span class=special>&gt;::</span><span class=identifier>type</span>
<span class=identifier>multi_index_container</span><span class=special>::</span><span class=identifier>nth_type</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;::</span><span class=identifier>type</span>
</pre></blockquote>
<p>
so the lists are radically different.
</p>
<h3><a name="synthesis">Synthesis</a></h3>
<p>
Although typically indices are specified by means of the
<code>indexed_by</code> construct, actually any Mp11 list can be provided instead:
</p>
<blockquote><pre>
<span class=keyword>using</span> <span class=identifier>index_list_t</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;&gt;</span> <span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>index_list_t</span>
<span class=special>&gt;</span> <span class=identifier>indexed_t</span><span class=special>;</span>
</pre></blockquote>
<p>
This possibility enables the synthesis of instantiations of
<code>multi_index_container</code> through metaprogramming, as the following
example shows:
</p>
<blockquote><pre>
<span class=comment>// original multi_index_container instantiation</span>
<span class=keyword>using</span> <span class=identifier>indexed_t1</span><span class=special>=</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;;</span>
<span class=comment>// we take its index list and add an index</span>
<span class=keyword>using</span> <span class=identifier>index_list_t2</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>mp11</span><span class=special>::</span><span class=identifier>mp_push_front</span><span class=special>&lt;</span>
<span class=identifier>indexed_t1</span><span class=special>::</span><span class=identifier>index_specifier_type_list</span><span class=special>,</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;</span>
<span class=special>&gt;;</span>
<span class=comment>// augmented multi_index_container</span>
<span class=keyword>using</span> <span class=identifier>indexed_t2</span><span class=special>=</span><span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>index_list_t2</span>
<span class=special>&gt;;</span>
</pre></blockquote>
<hr>
<div class="prev_link"><a href="debug.html"><img src="../prev.gif" alt="debugging support" border="0"><br>
Debugging support
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
Boost.MultiIndex tutorial
</a></div>
<div class="next_link"><a href="../reference/index.html"><img src="../next.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised October 25th 2025</p>
<p>&copy; Copyright 2003-2025 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>
+24 -15
View File
@@ -1,57 +1,66 @@
# Boost.MultiIndex examples Jamfile
#
# Copyright 2003-2005 Joaquín M López Muñoz.
# Copyright 2003-2007 Joaqun M Lpez Muoz.
# 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 ;
project : requirements <library>/boost/multi_index//boost_multi_index ;
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)
/boost/tokenizer//boost_tokenizer
;
exe fun_key
: fun_key.cpp
;
exe hashed
: hashed.cpp
: <include>$(BOOST_ROOT)
/boost/tokenizer//boost_tokenizer
;
exe memfun_key
: memfun_key.cpp
: <include>$(BOOST_ROOT)
exe ip_allocator
: ip_allocator.cpp
/boost/interprocess//boost_interprocess
: <threading>multi
;
exe non_default_ctor
: non_default_ctor.cpp
: <include>$(BOOST_ROOT)
;
exe random_access
: random_access.cpp
/boost/tokenizer//boost_tokenizer
;
exe rearrange
: rearrange.cpp
/boost/random//boost_random
;
exe sequenced
: sequenced.cpp
: <include>$(BOOST_ROOT)
/boost/tokenizer//boost_tokenizer
;
exe serialization
: serialization.cpp
<lib>../../serialization/build/boost_serialization
: <include>$(BOOST_ROOT)
std::locale-support
/boost/serialization//boost_serialization
;
+6 -13
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex basic example.
*
* Copyright 2003-2005 Joaquín M López Muñoz.
* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -47,12 +47,8 @@ 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 unique index sorted by employee::id,
* - a non-unique index sorted by employee::name,
* - a non-unique index sorted by employee::age.
*/
@@ -61,18 +57,15 @@ typedef multi_index_container<
employee,
indexed_by<
ordered_unique<
tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
tag<id>, member<employee,int,&employee::id> >,
ordered_non_unique<
tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
tag<name>,member<employee,std::string,&employee::name> >,
ordered_non_unique<
tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >
tag<age>, member<employee,int,&employee::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 */
)
void print_out_by(const MultiIndexContainer& s)
{
/* obtain a reference to the index tagged by Tag */
+10 -47
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of a bidirectional map.
*
* Copyright 2003-2005 Joaquín M López Muñoz.
* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -18,7 +18,6 @@
#include <boost/multi_index/ordered_index.hpp>
#include <iostream>
#include <string>
#include <utility>
using boost::multi_index_container;
using namespace boost::multi_index;
@@ -35,31 +34,15 @@ struct to{};
template<typename FromType,typename ToType>
struct bidirectional_map
{
typedef std::pair<FromType,ToType> value_type;
struct value_type
{
value_type(const FromType& first_,const ToType& second_):
first(first_),second(second_)
{}
#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
FromType first;
ToType second;
};
/* A bidirectional map can be simulated as a multi_index_container
* of pairs of (FromType,ToType) with two unique indices, one
@@ -75,8 +58,6 @@ struct bidirectional_map
tag<to>, member<value_type,ToType,&value_type::second> >
>
> type;
#endif
};
/* a dictionary is a bidirectional map from strings to strings */
@@ -101,22 +82,6 @@ int main()
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);
@@ -129,14 +94,12 @@ int main()
else{
/* word not found in Spanish, try our luck in English */
dictionary::index_iterator<to>::type it2=d.get<to>().find(word);
dictionary::index<to>::type::iterator it2=d.get<to>().find(word);
if(it2!=d.get<to>().end()){
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
}
else std::cout<<"No such word in the dictionary"<<std::endl;
}
#endif
return 0;
}
+14 -18
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example: complex searches and foreign keys.
*
* Copyright 2003-2005 Joaquín M López Muñoz.
* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -88,10 +88,6 @@ struct car_model
}
};
/* 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
@@ -102,7 +98,7 @@ typedef multi_index_container<
car_manufacturer,
indexed_by<
ordered_unique<
BOOST_MULTI_INDEX_MEMBER(car_manufacturer,std::string,name)
member<car_manufacturer,std::string,&car_manufacturer::name>
>
>
> car_manufacturer_table;
@@ -118,18 +114,18 @@ typedef multi_index_container<
car_model,
indexed_by<
ordered_unique<
tag<model>,BOOST_MULTI_INDEX_MEMBER(car_model,std::string,model)
tag<model>,member<car_model,std::string,&car_model::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)
member<car_manufacturer,const std::string,&car_manufacturer::name>,
member<
car_model,const car_manufacturer *,&car_model::manufacturer>
>
>,
ordered_non_unique<
tag<price>,BOOST_MULTI_INDEX_MEMBER(car_model,int,price)
tag<price>,member<car_model,int,&car_model::price>
>
>
> car_table;
@@ -138,7 +134,7 @@ typedef multi_index_container<
* 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
* 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.
*/
@@ -146,7 +142,7 @@ typedef multi_index_container<
typedef multi_index_container<
const car_model*,
indexed_by<
ordered_non_unique<BOOST_MULTI_INDEX_MEMBER(car_model,const int,price)>
ordered_non_unique<member<car_model,const int,&car_model::price> >
>
> car_table_price_view;
@@ -159,9 +155,9 @@ typedef multi_index_container<
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)
member<car_manufacturer,const std::string,&car_manufacturer::name>,
member<
car_model,const car_manufacturer * const,&car_model::manufacturer>
>
>
>
@@ -245,7 +241,7 @@ int main()
/* find all the cars for the manufacturer given */
index_iterator<car_table,manufacturer>::type ic0,ic1;
boost::multi_index::index<car_table,manufacturer>::type::iterator ic0,ic1;
boost::tuples::tie(ic0,ic1)=get<manufacturer>(ct).equal_range(cm);
/* construct a view (indexed by price) with these */
@@ -280,7 +276,7 @@ int main()
/* find the cars in the range given */
index_iterator<car_table,price>::type ic0,ic1;
boost::multi_index::index<car_table,price>::type::iterator ic0,ic1;
ic0=get<price>(ct).lower_bound(min_price);
ic1=get<price>(ct).upper_bound(max_price);
+11 -24
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of composite keys.
*
* Copyright 2003-2005 Joaquín M López Muñoz.
* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -18,6 +18,7 @@
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/next_prior.hpp>
#include <boost/tokenizer.hpp>
#include <functional>
#include <iostream>
@@ -56,43 +57,29 @@ struct file_entry
* 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.
* NB: The use of derivation here instead of simple typedef helps produce
* shorter symbol names in compilation
*/
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)
member<file_entry,const file_entry*,&file_entry::dir>,
member<file_entry,std::string,&file_entry::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)
member<file_entry,const file_entry* const,&file_entry::dir>,
member<file_entry,unsigned,&file_entry::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
>,
ordered_unique<name_key>,
/* 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
>
ordered_non_unique<size_key>
>
> file_system;
@@ -287,7 +274,7 @@ int main()
continue;
}
it->second->execute(++tok.begin(),tok.end());
it->second->execute(boost::next(tok.begin()),tok.end());
}
return 0;
+27 -8
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of member functions used as key extractors.
/* Boost.MultiIndex example of functions used as key extractors.
*
* Copyright 2003-2005 Joaquín M López Muñoz.
* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -14,6 +14,7 @@
#endif
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/global_fun.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <iostream>
@@ -29,8 +30,8 @@ using namespace boost::multi_index;
struct name_record
{
name_record(std::string given_name,std::string family_name):
given_name(given_name),family_name(family_name)
name_record(std::string given_name_,std::string family_name_):
given_name(given_name_),family_name(family_name_)
{}
std::string name()const
@@ -46,16 +47,23 @@ private:
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.
std::string::size_type name_record_length(const name_record& r)
{
return r.name().size();
}
/* multi_index_container with indices based on name_record::name()
* and name_record_length().
*/
typedef multi_index_container<
name_record,
indexed_by<
ordered_unique<
BOOST_MULTI_INDEX_CONST_MEM_FUN(name_record,std::string,name)
const_mem_fun<name_record,std::string,&name_record::name>
>,
ordered_non_unique<
global_fun<const name_record&,std::string::size_type,name_record_length>
>
>
> name_record_set;
@@ -71,9 +79,20 @@ int main()
/* list the names in ns in phonebook order */
std::cout<<"Phonenook order\n"
<<"---------------"<<std::endl;
for(name_record_set::iterator it=ns.begin();it!=ns.end();++it){
std::cout<<it->name()<<std::endl;
}
/* list the names in ns according to their length*/
std::cout<<"\nLength order\n"
<< "------------"<<std::endl;
for(nth_index<name_record_set,1>::type::iterator it1=get<1>(ns).begin();
it1!=get<1>(ns).end();++it1){
std::cout<<it1->name()<<std::endl;
}
return 0;
}
+17 -19
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of hashed indices.
*
* Copyright 2003-2005 Joaquín M López Muñoz.
* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -37,19 +37,15 @@ struct word_counter_entry
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),
member<word_counter_entry,unsigned int,&word_counter_entry::occurrences>,
std::greater<unsigned int> /* sorted beginning with most frequent */
>,
hashed_unique<
BOOST_MULTI_INDEX_MEMBER(word_counter_entry,std::string,word)
member<word_counter_entry,std::string,&word_counter_entry::word>
>
>
> word_counter;
@@ -66,25 +62,27 @@ typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
int main()
{
/* boostinspect:noascii */
std::string text=
"En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha "
"mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga "
"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 "
"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 "
"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 "
"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 "
"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 "
"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.";
"narración dél no se salga un punto de la verdad.";
/* feed the text into the container */
+288
View File
@@ -0,0 +1,288 @@
/* Boost.MultiIndex example of use of Boost.Interprocess allocators.
*
* Copyright 2003-2026 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
using boost::multi_index_container;
using namespace boost::multi_index;
namespace bip=boost::interprocess;
/* shared_string is a string type placeable in shared memory,
* courtesy of Boost.Interprocess.
*/
typedef bip::basic_string<
char,std::char_traits<char>,
bip::allocator<char,bip::managed_mapped_file::segment_manager>
> shared_string;
/* Book record. All its members can be placed in shared memory,
* hence the structure itself can too.
*/
struct book
{
shared_string name;
shared_string author;
unsigned pages;
unsigned prize;
book(const shared_string::allocator_type& al):
name(al),author(al),pages(0),prize(0)
{}
friend std::ostream& operator<<(std::ostream& os,const book& b)
{
os<<b.author<<": \""<<b.name<<"\", $"<<b.prize<<", "<<b.pages<<" pages\n";
return os;
}
};
/* partial_str_less allows for partial searches taking into account
* only the first n chars of the strings compared against. See
* Tutorial: Basics: Special lookup operations for more info on this
* type of comparison functors.
*/
/* partial_string is a mere string holder used to differentiate from
* a plain string.
*/
struct partial_string
{
partial_string(const shared_string& str):str(str){}
shared_string str;
};
struct partial_str_less
{
bool operator()(const shared_string& x,const shared_string& y)const
{
return x<y;
}
bool operator()(const shared_string& x,const partial_string& y)const
{
return x.substr(0,y.str.size())<y.str;
}
bool operator()(const partial_string& x,const shared_string& y)const
{
return x.str<y.substr(0,x.str.size());
}
};
/* Define a multi_index_container of book records with indices on
* author, name and prize. The index on names allows for partial
* searches. This container can be placed in shared memory because:
* * book can be placed in shared memory.
* * We are using a Boost.Interprocess specific allocator.
*/
typedef multi_index_container<
book,
indexed_by<
ordered_non_unique<
member<book,shared_string,&book::author>
>,
ordered_non_unique<
member<book,shared_string,&book::name>,
partial_str_less
>,
ordered_non_unique<
member<book,unsigned,&book::prize>
>
>,
bip::allocator<book,bip::managed_mapped_file::segment_manager>
> book_container;
/* A small utility to get data entered via std::cin */
template<typename T>
void enter(const char* msg,T& t)
{
std::cout<<msg;
std::string str;
std::getline(std::cin,str);
std::istringstream iss(str);
iss>>t;
}
void enter(const char* msg,std::string& str)
{
std::cout<<msg;
std::getline(std::cin,str);
}
void enter(const char* msg,shared_string& str)
{
std::cout<<msg;
std::string stdstr;
std::getline(std::cin,stdstr);
str=stdstr.c_str();
}
int main()
{
/* Create (or open) the memory mapped file where the book container
* is stored, along with a mutex for synchronized access.
*/
bip::managed_mapped_file seg(
bip::open_or_create,"./book_container.db",
65536);
bip::named_mutex mutex(
bip::open_or_create,"7FD6D7E8-320B-11DC-82CF-F0B655D89593");
/* create or open the book container in shared memory */
book_container* pbc=seg.find_or_construct<book_container>("book container")(
book_container::ctor_args_list(),
book_container::allocator_type(seg.get_segment_manager()));
std::string command_info=
"1. list books by author\n"
"2. list all books by prize\n"
"3. insert a book\n"
"4. delete a book\n"
"0. exit\n";
std::cout<<command_info;
/* main loop */
for(bool exit=false;!exit;){
int command=-1;
enter("command: ",command);
switch(command){
case 0:{ /* exit */
exit=true;
break;
}
case 1:{ /* list books by author */
std::string author;
enter("author (empty=all authors): ",author);
/* operations with the container must be mutex protected */
bip::scoped_lock<bip::named_mutex> lock(mutex);
std::pair<book_container::iterator,book_container::iterator> rng;
if(author.empty()){
rng=std::make_pair(pbc->begin(),pbc->end());
}
else{
rng=pbc->equal_range(
shared_string(
author.c_str(),
shared_string::allocator_type(seg.get_segment_manager())));
}
if(rng.first==rng.second){
std::cout<<"no entries\n";
}
else{
std::copy(
rng.first,rng.second,std::ostream_iterator<book>(std::cout));
}
break;
}
case 2:{ /* list all books by prize */
bip::scoped_lock<bip::named_mutex> lock(mutex);
std::copy(
get<2>(*pbc).begin(),get<2>(*pbc).end(),
std::ostream_iterator<book>(std::cout));
break;
}
case 3:{ /* insert a book */
book b(shared_string::allocator_type(seg.get_segment_manager()));
enter("author: ",b.author);
enter("name: " ,b.name);
enter("prize: " ,b.prize);
enter("pages: " ,b.pages);
std::cout<<"insert the following?\n"<<b<<"(y/n): ";
char yn='n';
enter("",yn);
if(yn=='y'||yn=='Y'){
bip::scoped_lock<bip::named_mutex> lock(mutex);
pbc->insert(b);
}
break;
}
case 4:{ /* delete a book */
shared_string name(
shared_string::allocator_type(seg.get_segment_manager()));
enter(
"name of the book (you can enter\nonly the first few characters): ",
name);
typedef nth_index<book_container,1>::type index_by_name;
index_by_name& idx=get<1>(*pbc);
index_by_name::iterator it;
book b(shared_string::allocator_type(seg.get_segment_manager()));
{
/* Look for a book whose title begins with name. Note that we
* are unlocking after doing the search so as to not leave the
* container blocked during user prompting. That is also why a
* local copy of the book is done.
*/
bip::scoped_lock<bip::named_mutex> lock(mutex);
it=idx.find(partial_string(name));
if(it==idx.end()){
std::cout<<"no such book found\n";
break;
}
b=*it;
}
std::cout<<"delete the following?\n"<<b<<"(y/n): ";
char yn='n';
enter("",yn);
if(yn=='y'||yn=='Y'){
bip::scoped_lock<bip::named_mutex> lock(mutex);
idx.erase(it);
}
break;
}
default:{
std::cout<<"select one option:\n"<<command_info;
break;
}
}
}
return 0;
}
+1 -1
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of multi_index_container::ctor_args_list.
*
* Copyright 2003-2004 Joaqu匤 M Lez Muz.
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
+102
View File
@@ -0,0 +1,102 @@
/* Boost.MultiIndex example of use of random access indices.
*
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/tokenizer.hpp>
#include <algorithm>
#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<
random_access<>,
ordered_non_unique<identity<std::string> >
>
> text_container;
/* ordered index */
typedef nth_index<text_container,1>::type ordered_text;
/* Helper function for obtaining the position of an element in the
* container.
*/
template<typename IndexIterator>
text_container::size_type text_position(
const text_container& tc,IndexIterator it)
{
/* project to the base index and calculate offset from begin() */
return project<0>(tc,it)-tc.begin();
}
typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
int main()
{
std::string text=
"'Oh, you wicked little thing!' cried Alice, catching up the kitten, "
"and giving it a little kiss to make it understand that it was in "
"disgrace. 'Really, Dinah ought to have taught you better manners! You "
"ought, Dinah, you know you ought!' she added, looking reproachfully at "
"the old cat, and speaking in as cross a voice as she could manage "
"-- and then she scrambled back into the armchair, taking the kitten and "
"the worsted with her, and began winding up the ball again. But she "
"didn't get on very fast, as she was talking all the time, sometimes to "
"the kitten, and sometimes to herself. Kitty sat very demurely on her "
"knee, pretending to watch the progress of the winding, and now and then "
"putting out one paw and gently touching the ball, as if it would be glad "
"to help, if it might.";
/* feed the text into the container */
text_container tc;
tc.reserve(text.size()); /* makes insertion faster */
text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
std::copy(tok.begin(),tok.end(),std::back_inserter(tc));
std::cout<<"enter a position (0-"<<tc.size()-1<<"):";
text_container::size_type pos=tc.size();
std::cin>>pos;
if(pos>=tc.size()){
std::cout<<"out of bounds"<<std::endl;
}
else{
std::cout<<"the word \""<<tc[pos]<<"\" appears at position(s): ";
std::pair<ordered_text::iterator,ordered_text::iterator> p=
get<1>(tc).equal_range(tc[pos]);
while(p.first!=p.second){
std::cout<<text_position(tc,p.first++)<<" ";
}
std::cout<<std::endl;
}
return 0;
}
+251
View File
@@ -0,0 +1,251 @@
/* Boost.MultiIndex example of use of rearrange facilities.
*
* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif
#include <boost/config.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/random/binomial_distribution.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <random>
#include <vector>
using boost::multi_index_container;
using namespace boost::multi_index;
/* We model a card deck with a random access array containing
* card numbers (from 0 to 51), supplemented with an additional
* index which retains the start ordering.
*/
class deck
{
BOOST_STATIC_CONSTANT(std::size_t,num_cards=52);
typedef multi_index_container<
int,
indexed_by<
random_access<>, /* base index */
random_access<> /* "start" index */
>
> container_type;
container_type cont;
public:
deck()
{
cont.reserve(num_cards);
get<1>(cont).reserve(num_cards);
for(std::size_t i=0;i<num_cards;++i)cont.push_back(i);
}
typedef container_type::iterator iterator;
typedef container_type::size_type size_type;
iterator begin()const{return cont.begin();}
iterator end()const{return cont.end();}
size_type size()const{return cont.size();}
template<typename InputIterator>
void rearrange(InputIterator it)
{
cont.rearrange(it);
}
void reset()
{
/* simply rearrange the base index like the start index */
cont.rearrange(get<1>(cont).begin());
}
std::size_t position(int i)const
{
/* The position of a card in the deck is calculated by locating
* the card through the start index (which is ordered), projecting
* to the base index and diffing with the begin position.
* Resulting complexity: constant.
*/
return project<0>(cont,get<1>(cont).begin()+i)-cont.begin();
}
std::size_t rising_sequences()const
{
/* Iterate through all cards and increment the sequence count
* when the current position is left to the previous.
* Resulting complexity: O(n), n=num_cards.
*/
std::size_t s=1;
std::size_t last_pos=0;
for(std::size_t i=0;i<num_cards;++i){
std::size_t pos=position(i);
if(pos<last_pos)++s;
last_pos=pos;
}
return s;
}
};
/* A vector of reference_wrappers to deck elements can be used
* as a view to the deck container.
* We use a special implicit_reference_wrapper having implicit
* ctor from its base type, as this simplifies the use of generic
* techniques on the resulting data structures.
*/
template<typename T>
class implicit_reference_wrapper:public boost::reference_wrapper<T>
{
private:
typedef boost::reference_wrapper<T> super;
public:
implicit_reference_wrapper(T& t):super(t){}
};
typedef std::vector<implicit_reference_wrapper<const int> > deck_view;
/* Riffle shuffle is modeled like this: A cut is selected in the deck
* following a binomial distribution. Then, cards are randomly selected
* from one packet or the other with probability proportional to
* packet size.
*/
template<typename RandomAccessIterator,typename OutputIterator>
void riffle_shuffle(
RandomAccessIterator first,RandomAccessIterator last,
OutputIterator out)
{
static boost::mt19937 rnd_gen;
typedef typename std::iterator_traits<
RandomAccessIterator>::difference_type difference_type;
typedef boost::binomial_distribution<
difference_type> rnd_cut_select_type;
typedef boost::uniform_real<> rnd_deck_select_type;
rnd_cut_select_type cut_select(last-first);
RandomAccessIterator middle=first+cut_select(rnd_gen);
difference_type s0=middle-first;
difference_type s1=last-middle;
rnd_deck_select_type deck_select;
while(s0!=0&&s1!=0){
if(deck_select(rnd_gen)<(double)s0/(s0+s1)){
*out++=*first++;
--s0;
}
else{
*out++=*middle++;
--s1;
}
}
std::copy(first,first+s0,out);
std::copy(middle,middle+s1,out);
}
struct riffle_shuffler
{
void operator()(deck& d)const
{
dv.clear();
dv.reserve(d.size());
riffle_shuffle(
d.begin(),d.end(),std::back_inserter(dv)); /* do the shuffling */
d.rearrange(dv.begin()); /* apply to the deck */
}
private:
mutable deck_view dv;
};
/* A truly random shuffle (up to stdlib implementation quality) using
* std::shuffle.
*/
struct random_shuffler
{
void operator()(deck& d)
{
dv.clear();
dv.reserve(d.size());
std::copy(d.begin(),d.end(),std::back_inserter(dv));
shuffle_view();
d.rearrange(dv.begin()); /* apply to the deck */
}
private:
deck_view dv;
std::mt19937 e;
void shuffle_view()
{
std::shuffle(dv.begin(),dv.end(),e);
}
};
/* Repeat a given shuffling algorithm repeats_num times
* and obtain the resulting rising sequences number. Average
* for tests_num trials.
*/
template<typename Shuffler>
double shuffle_test(
unsigned int repeats_num,unsigned int tests_num
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Shuffler))
{
deck d;
Shuffler sh;
unsigned long total=0;
for(unsigned int n=0;n<tests_num;++n){
for(unsigned m=0;m<repeats_num;++m)sh(d);
total+=d.rising_sequences();
d.reset();
}
return (double)total/tests_num;
}
int main()
{
unsigned rifs_num=0;
unsigned tests_num=0;
std::cout<<"number of riffle shuffles (vg 5):";
std::cin>>rifs_num;
std::cout<<"number of tests (vg 1000):";
std::cin>>tests_num;
std::cout<<"shuffling..."<<std::endl;
std::cout<<"riffle shuffling\n"
" avg number of rising sequences: "
<<shuffle_test<riffle_shuffler>(rifs_num,tests_num)
<<std::endl;
std::cout<<"random shuffling\n"
" avg number of rising sequences: "
<<shuffle_test<random_shuffler>(1,tests_num)
<<std::endl;
return 0;
}
+1 -1
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of sequenced indices.
*
* Copyright 2003-2005 Joaqu匤 M Lez Muz.
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
+2 -2
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of serialization of a MRU list.
*
* Copyright 2003-2005 Joaquín M López Muñoz.
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -50,7 +50,7 @@ public:
typedef Item item_type;
typedef typename item_list::iterator iterator;
mru_list(std::size_t max_num_items):max_num_items(max_num_items){}
mru_list(std::size_t max_num_items_):max_num_items(max_num_items_){}
void insert(const item_type& item)
{
File diff suppressed because it is too large Load Diff
@@ -1,48 +0,0 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP
#define BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
/* In those compilers that do not accept the member template friend syntax,
* some protected and private sections might need to be specified as
* public.
*/
#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS public
#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS public
#else
#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS protected
#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS private
#endif
/* GCC does not correctly support in-class using declarations for template
* functions. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9810
* MSVC 7.1/8.0 seem to have a similar problem, though the conditions in
* which the error happens are not that simple. I have yet to isolate this
* into a snippet suitable for bug reporting.
*/
#if BOOST_WORKAROUND(__GNUC__, <3)||\
BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\
BOOST_WORKAROUND(BOOST_MSVC,==1310)||\
BOOST_WORKAROUND(BOOST_MSVC,==1400)
#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS public
#else
#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS private
#endif
#endif
@@ -0,0 +1,38 @@
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP
#define BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
namespace boost{
namespace multi_index{
namespace detail{
template<typename T>
void adl_swap(T& x,T& y)
{
using std::swap;
swap(x,y);
}
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -0,0 +1,76 @@
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_ANY_CONTAINER_VIEW_HPP
#define BOOST_MULTI_INDEX_DETAIL_ANY_CONTAINER_VIEW_HPP
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* type-erased, non-owning view over a ConstIterator-container's range */
template<typename ConstIterator>
class any_container_view
{
public:
template<typename Container>
any_container_view(const Container& x):px(&x),pt(vtable_for<Container>()){}
const void* container()const{return px;}
ConstIterator begin()const{return pt->begin(px);}
ConstIterator end()const{return pt->end(px);}
private:
struct vtable
{
ConstIterator (*begin)(const void*);
ConstIterator (*end)(const void*);
};
template<typename Container>
static ConstIterator begin_for(const void* px)
{
return static_cast<const Container*>(px)->begin();
}
template<typename Container>
static ConstIterator end_for(const void* px)
{
return static_cast<const Container*>(px)->end();
}
template<typename Container>
vtable* vtable_for()
{
static vtable v=
{
&begin_for<Container>,
&end_for<Container>
};
return &v;
}
const void* px;
vtable* pt;
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,15 +9,16 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP
#define BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/aligned_storage.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/noncopyable.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/core/serialization.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
namespace boost{
@@ -33,7 +34,7 @@ struct archive_constructed:private noncopyable
template<class Archive>
archive_constructed(Archive& ar,const unsigned int version)
{
serialization::load_construct_data_adl(ar,&get(),version);
core::load_construct_data_adl(ar,&get(),version);
BOOST_TRY{
ar>>get();
}
@@ -47,9 +48,9 @@ struct archive_constructed:private noncopyable
template<class Archive>
archive_constructed(const char* name,Archive& ar,const unsigned int version)
{
serialization::load_construct_data_adl(ar,&get(),version);
core::load_construct_data_adl(ar,&get(),version);
BOOST_TRY{
ar>>serialization::make_nvp(name,get());
ar>>core::make_nvp(name,get());
}
BOOST_CATCH(...){
(&get())->~T();
@@ -63,10 +64,14 @@ struct archive_constructed:private noncopyable
(&get())->~T();
}
T& get(){return *static_cast<T*>(space.address());}
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
T& get(){return *reinterpret_cast<T*>(&space);}
#include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
private:
aligned_storage<sizeof(T)> space;
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
};
} /* namespace multi_index::detail */
@@ -0,0 +1,129 @@
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_AUGMENTED_STDTUPLE_HPP
#define BOOST_MULTI_INDEX_DETAIL_AUGMENTED_STDTUPLE_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/function.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/integer_sequence.hpp>
#include <boost/mp11/integral.hpp>
#include <boost/tuple/tuple.hpp>
#include <tuple>
#include <type_traits>
namespace boost{
namespace multi_index{
namespace detail{
/* augmented_stdtuple<Ts...> derives from std::tuple<Ts...> and provides the
* following non-standard constructors:
*
* - augmented_stdtuple(const Ts& = Ts()...) (this signature is not legal C++,
* shown for explanatory purposes).
* - augmented_stdtuple(boost::tuple<Ts...>) if sizeof...(Ts) does not exceed
* the maximum length of a boost::tuple (10 as of this writing).
*/
template<typename T,typename U>
using is_convertible_to_cref=std::is_convertible<T,const U&>;
template<typename FromList,typename ToList,typename=void>
struct are_convertible_to_crefs:mp11::mp_false{};
template<typename FromList,typename ToList>
struct are_convertible_to_crefs<
FromList,ToList,
typename std::enable_if<
(mp11::mp_size<FromList>::value<=mp11::mp_size<ToList>::value)
>::type
>:
mp11::mp_apply<
mp11::mp_and,
mp11::mp_transform<
is_convertible_to_cref,
FromList,
mp11::mp_take_c<ToList,mp11::mp_size<FromList>::value>
>
>
{};
template<typename... Ts>
struct augmented_stdtuple:std::tuple<Ts...>
{
private:
using super=std::tuple<Ts...>;
static constexpr std::size_t N=sizeof...(Ts);
template<typename... Args>
using are_convertible_to_crefs=
typename detail::are_convertible_to_crefs<mp11::mp_list<Args...>,super>;
struct boost_tuple_too_short{};
using boost_tuple_arg=mp11::mp_eval_if_c<
(mp11::mp_size<boost::tuple<>>::value < N),
boost_tuple_too_short,
boost::tuple,Ts...
>;
struct full_args_ctor{};
augmented_stdtuple(full_args_ctor,const Ts&... args):super(args...){}
struct partial_args_ctor{};
template<std::size_t... Is,typename... Args>
augmented_stdtuple(
partial_args_ctor,mp11::index_sequence<Is...>,Args&&... args):
augmented_stdtuple(
full_args_ctor{},
std::forward<Args>(args)...,
typename std::tuple_element<sizeof...(Args)+Is,super>::type()...)
{}
struct boost_tuple_ctor{};
template<std::size_t... Is>
augmented_stdtuple(
boost_tuple_ctor,mp11::index_sequence<Is...>,const boost_tuple_arg& x):
super(tuples::get<Is>(x)...)
{}
public:
template<
typename... Args,
typename std::enable_if<
are_convertible_to_crefs<Args&&...>::value
>::type* =nullptr
>
augmented_stdtuple(Args&&... args):
augmented_stdtuple(
partial_args_ctor(),mp11::make_index_sequence<N-sizeof...(Args)>(),
std::forward<Args>(args)...)
{}
augmented_stdtuple(const super& x):super(x){}
augmented_stdtuple(const boost_tuple_arg& x):
augmented_stdtuple(
boost_tuple_ctor(),mp11::make_index_sequence<N>(),x)
{}
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
+36 -16
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,14 +9,16 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP
#define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/noncopyable.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/multi_index/detail/adl_swap.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <memory>
namespace boost{
@@ -38,34 +40,52 @@ namespace detail{
* "of zero length", http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14176
* C++ Standard Library Defect Report List (Revision 28), issue 199
* "What does allocate(0) return?",
* http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#199
* http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199
*/
template<typename T,typename Allocator=std::allocator<T> >
struct auto_space:private noncopyable
{
explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1):
al_(al),n_(n),data_(n_?al_.allocate(n_):0)
typedef allocator_rebind_t<Allocator,T> allocator;
typedef allocator_pointer_t<allocator> pointer;
typedef allocator_size_type_t<allocator> size_type;
explicit auto_space(const Allocator& al=Allocator(),size_type n=1):
al_(al),n_(n),data_(n_?allocator_allocate(al_,n_):pointer(0))
{}
~auto_space()
{
if(n_)al_.deallocate(data_,n_);
}
~auto_space(){if(n_)allocator_deallocate(al_,data_,n_);}
T* data()const{return data_;}
Allocator get_allocator()const{return al_;}
pointer data()const{return data_;}
void swap(auto_space& x)
{
swap(
x,
boost::integral_constant<
bool,
allocator_propagate_on_container_swap_t<allocator>::value>());
}
void swap(auto_space& x,boost::true_type /* swap_allocators */)
{
adl_swap(al_,x.al_);
std::swap(n_,x.n_);
std::swap(data_,x.data_);
}
void swap(auto_space& x,boost::false_type /* swap_allocators */)
{
std::swap(n_,x.n_);
std::swap(data_,x.data_);
}
private:
typename boost::detail::allocator::rebind_to<
Allocator,T>::type al_;
std::size_t n_;
T* data_;
allocator al_;
size_type n_;
pointer data_;
};
template<typename T,typename Allocator>
@@ -0,0 +1,36 @@
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP
#define BOOST_MULTI_INDEX_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <stdexcept>
namespace boost{
namespace multi_index{
namespace detail{
struct bad_archive_exception:std::runtime_error
{
bad_archive_exception():std::runtime_error("Invalid or corrupted archive"){}
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
+21 -43
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,18 +9,16 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP
#define BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mp11/integral.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/multi_index/detail/index_base.hpp>
#include <boost/multi_index/detail/is_index_list.hpp>
#include <boost/multi_index/detail/msvc_index_specifier.hpp>
#include <boost/static_assert.hpp>
namespace boost{
@@ -29,51 +27,31 @@ namespace multi_index{
namespace detail{
/* MPL machinery to construct a linear hierarchy of indices out of
* a index list.
/* Mp11 machinery to construct a linear hierarchy of indices out of
* an index list.
*/
#if BOOST_WORKAROUND(BOOST_MSVC,<1310)
struct index_applier
{
template<typename IndexSpecifierMeta,typename SuperMeta>
struct apply:
msvc_index_specifier<IndexSpecifierMeta::type>::
template result_index_class<SuperMeta>
{
};
};
#else
struct index_applier
{
template<typename IndexSpecifierMeta,typename Super>
struct apply
{
typedef typename IndexSpecifierMeta::type index_specifier;
typedef typename index_specifier::
BOOST_NESTED_TEMPLATE index_class<Super>::type type;
};
};
#endif
template<typename N,typename Mp11IndexSpecifierList,typename SuperMeta>
using nth_layer_index=typename mp11::mp_at<Mp11IndexSpecifierList,N>::
template index_class<SuperMeta>::type;
template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
struct nth_layer
{
BOOST_STATIC_CONSTANT(int,length=mpl::size<IndexSpecifierList>::value);
typedef typename mpl::eval_if_c<
N==length,
mpl::identity<index_base<Value,IndexSpecifierList,Allocator> >,
mpl::apply2<
index_applier,
mpl::at_c<IndexSpecifierList,N>,
nth_layer<N+1,Value,IndexSpecifierList,Allocator>
>
>::type type;
using Mp11IndexSpecifierList=detail::mp11_index_list<IndexSpecifierList>;
using type=mp11::mp_eval_if_c<
N==mp11::mp_size<Mp11IndexSpecifierList>::value,
index_base<Value,IndexSpecifierList,Allocator>,
nth_layer_index,
mp11::mp_int<N>,
Mp11IndexSpecifierList,
nth_layer<N+1,Value,IndexSpecifierList,Allocator>
>;
};
template<typename Value,typename IndexSpecifierList,typename Allocator>
struct multi_index_base_type:nth_layer<0,Value,IndexSpecifierList,Allocator>
struct multi_index_base_type:
nth_layer<0,Value,IndexSpecifierList,Allocator>
{
BOOST_STATIC_ASSERT(detail::is_index_list<IndexSpecifierList>::value);
};
@@ -0,0 +1,118 @@
/* Copyright 2003-2026 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <boost/operators.hpp>
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/core/serialization.hpp>
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* Iterator class for node-based indices with bidirectional
* iterators (ordered and sequenced indices.)
*/
template<typename Node>
class bidir_node_iterator:
public bidirectional_iterator_helper<
bidir_node_iterator<Node>,
typename Node::value_type,
typename Node::difference_type,
const typename Node::value_type*,
const typename Node::value_type&>
{
public:
/* coverity[uninit_ctor]: suppress warning */
bidir_node_iterator(){}
explicit bidir_node_iterator(Node* node_):node(node_){}
const typename Node::value_type& operator*()const
{
return node->value();
}
bidir_node_iterator& operator++()
{
Node::increment(node);
return *this;
}
bidir_node_iterator& operator--()
{
Node::decrement(node);
return *this;
}
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
/* Serialization. As for why the following is public,
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
*/
template<class Archive>
void serialize(Archive& ar,const unsigned int version)
{
core::split_member(ar,*this,version);
}
typedef typename Node::base_type node_base_type;
template<class Archive>
void save(Archive& ar,const unsigned int)const
{
node_base_type* bnode=get_node();
ar<<core::make_nvp("pointer",bnode);
}
template<class Archive>
void load(Archive& ar,const unsigned int)
{
node_base_type* bnode;
ar>>core::make_nvp("pointer",bnode);
node=typename Node::pointer(static_cast<Node*>(bnode));
}
#endif
/* get_node is not to be used by the user */
typedef Node node_type;
Node* get_node()const{return raw_ptr<Node*>(node);}
private:
typename Node::pointer node;
};
template<typename Node>
bool operator==(
const bidir_node_iterator<Node>& x,
const bidir_node_iterator<Node>& y)
{
return x.get_node()==y.get_node();
}
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
+129 -82
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,21 +9,26 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP
#define BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/core/allocator_access.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
#include <boost/multi_index/detail/hash_index_node.hpp>
#include <boost/noncopyable.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <cstddef>
#include <limits.h>
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/archive/archive_exception.hpp>
#include <boost/serialization/access.hpp>
#include <boost/core/serialization.hpp>
#include <boost/multi_index/detail/bad_archive_exception.hpp>
#include <boost/throw_exception.hpp>
#endif
@@ -35,103 +40,154 @@ namespace detail{
/* bucket structure for use by hashed indices */
#define BOOST_MULTI_INDEX_BA_SIZES_32BIT \
(53ul)(97ul)(193ul)(389ul)(769ul) \
(1543ul)(3079ul)(6151ul)(12289ul)(24593ul) \
(49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \
(1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \
(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
(1610612741ul)(3221225473ul)
#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */
#define BOOST_MULTI_INDEX_BA_SIZES \
BOOST_MULTI_INDEX_BA_SIZES_32BIT \
(4294967291ul)
#else
/* obtained with aid from
* http://javaboutique.internet.com/prime_numb/
* http://www.rsok.com/~jrm/next_ten_primes.html
* and verified with
* http://www.alpertron.com.ar/ECM.HTM
*/
#define BOOST_MULTI_INDEX_BA_SIZES \
BOOST_MULTI_INDEX_BA_SIZES_32BIT \
(6442450939ul)(12884901893ul)(25769803751ul)(51539607551ul) \
(103079215111ul)(206158430209ul)(412316860441ul)(824633720831ul) \
(1649267441651ul)(3298534883309ul)(6597069766657ul)(13194139533299ul) \
(26388279066623ul)(52776558133303ul)(105553116266489ul)(211106232532969ul) \
(422212465066001ul)(844424930131963ul)(1688849860263953ul) \
(3377699720527861ul)(6755399441055731ul)(13510798882111483ul) \
(27021597764222939ul)(54043195528445957ul)(108086391056891903ul) \
(216172782113783843ul)(432345564227567621ul)(864691128455135207ul) \
(1729382256910270481ul)(3458764513820540933ul)(6917529027641081903ul) \
(13835058055282163729ul)(18446744073709551557ul)
#endif
template<bool _=true> /* templatized to have in-header static var defs */
class bucket_array_base:private noncopyable
{
protected:
inline static std::size_t next_prime(std::size_t n)
static const std::size_t sizes[
BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)];
static std::size_t size_index(std::size_t n)
{
static const std::size_t prime_list[]={
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul,
#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */
4294967291ul
#else
/* obtained with aid from
* http://javaboutique.internet.com/prime_numb/
* http://www.rsok.com/~jrm/next_ten_primes.html
* and verified with
* http://www.alpertron.com.ar/ECM.HTM
*/
6442450939ul, 12884901893ul, 25769803751ul, 51539607551ul,
103079215111ul, 206158430209ul, 412316860441ul, 824633720831ul,
1649267441651ul, 3298534883309ul, 6597069766657ul, 13194139533299ul,
26388279066623ul, 52776558133303ul, 105553116266489ul, 211106232532969ul,
422212465066001ul, 844424930131963ul, 1688849860263953ul,
3377699720527861ul, 6755399441055731ul, 13510798882111483ul,
27021597764222939ul, 54043195528445957ul, 108086391056891903ul,
216172782113783843ul, 432345564227567621ul, 864691128455135207ul,
1729382256910270481ul, 3458764513820540933ul, 6917529027641081903ul,
13835058055282163729ul, 18446744073709551557ul
#endif
};
static const std::size_t prime_list_size=
sizeof(prime_list)/sizeof(prime_list[0]);
std::size_t const *bound=
std::lower_bound(prime_list,prime_list+prime_list_size,n);
if(bound==prime_list+prime_list_size)bound--;
return *bound;
const std::size_t *bound=std::lower_bound(sizes,sizes+sizes_length,n);
if(bound==sizes+sizes_length)--bound;
return bound-sizes;
}
#define BOOST_MULTI_INDEX_BA_POSITION_CASE(z,n,_) \
case n:return hash%BOOST_PP_SEQ_ELEM(n,BOOST_MULTI_INDEX_BA_SIZES);
static std::size_t position(std::size_t hash,std::size_t size_index_)
{
/* Accelerate hash%sizes[size_index_] by replacing with a switch on
* hash%Ci expressions, each Ci a compile-time constant, which the
* compiler can implement without using integer division.
*/
switch(size_index_){
default: /* never used */
BOOST_PP_REPEAT(
BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES),
BOOST_MULTI_INDEX_BA_POSITION_CASE,~)
}
}
private:
static const std::size_t sizes_length;
};
template<bool _>
const std::size_t bucket_array_base<_>::sizes[]={
BOOST_PP_SEQ_ENUM(BOOST_MULTI_INDEX_BA_SIZES)
};
template<bool _>
const std::size_t bucket_array_base<_>::sizes_length=
sizeof(bucket_array_base<_>::sizes)/
sizeof(bucket_array_base<_>::sizes[0]);
#undef BOOST_MULTI_INDEX_BA_POSITION_CASE
#undef BOOST_MULTI_INDEX_BA_SIZES
#undef BOOST_MULTI_INDEX_BA_SIZES_32BIT
template<typename Allocator>
class bucket_array:public bucket_array_base
class bucket_array:bucket_array_base<>
{
typedef bucket_array_base<> super;
typedef hashed_index_base_node_impl<
allocator_rebind_t<
Allocator,
char
>
> base_node_impl_type;
public:
bucket_array(const Allocator& al,hashed_index_node_impl* end_,std::size_t size):
size_(bucket_array_base::next_prime(size)),
spc(al,size_+1)
typedef typename base_node_impl_type::base_pointer base_pointer;
typedef typename base_node_impl_type::pointer pointer;
bucket_array(const Allocator& al,pointer end_,std::size_t size_):
size_index_(super::size_index(size_)),
spc(al,static_cast<auto_space_size_type>(super::sizes[size_index_]+1))
{
clear();
end()->next()=end_;
end_->next()=end();
clear(end_);
}
std::size_t size()const
{
return size_;
return super::sizes[size_index_];
}
std::size_t position(std::size_t hash)const
{
return hash%size_;
return super::position(hash,size_index_);
}
hashed_index_node_impl* begin()const{return &buckets()[0];}
hashed_index_node_impl* end()const{return &buckets()[size_];}
hashed_index_node_impl* at(std::size_t n)const{return &buckets()[n];}
base_pointer begin()const{return buckets();}
base_pointer end()const{return buckets()+size();}
base_pointer at(std::size_t n)const{return buckets()+n;}
std::size_t first_nonempty(std::size_t n)const
void clear(pointer end_)
{
for(;;++n){
hashed_index_node_impl* x=at(n);
if(x->next()!=x)return n;
}
}
void clear()
{
for(hashed_index_node_impl* x=begin(),*y=end();x!=y;++x)x->next()=x;
}
for(base_pointer x=begin(),y=end();x!=y;++x)x->prior()=pointer(0);
end()->prior()=end_->prior()=end_;
end_->next()=end();
}
void swap(bucket_array& x)
{
std::swap(size_,x.size_);
std::swap(size_index_,x.size_index_);
spc.swap(x.spc);
}
private:
std::size_t size_;
auto_space<hashed_index_node_impl,Allocator> spc;
template<typename BoolConstant>
void swap(bucket_array& x,BoolConstant swap_allocators)
{
std::swap(size_index_,x.size_index_);
spc.swap(x.spc,swap_allocators);
}
hashed_index_node_impl* buckets()const
private:
typedef auto_space<base_node_impl_type,Allocator> auto_space_type;
typedef typename auto_space_type::size_type auto_space_size_type;
std::size_t size_index_;
auto_space_type spc;
base_pointer buckets()const
{
return spc.data();
}
@@ -168,28 +224,19 @@ void swap(bucket_array<Allocator>& x,bucket_array<Allocator>& y)
* somehow invalid archive.
*/
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
namespace serialization{
#else
namespace multi_index{
namespace detail{
#endif
template<class Archive,typename Allocator>
inline void load_construct_data(
Archive&,boost::multi_index::detail::bucket_array<Allocator>*,
const unsigned int)
{
throw_exception(
archive::archive_exception(archive::archive_exception::other_exception));
throw_exception(boost::multi_index::detail::bad_archive_exception());
}
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
} /* namespace serialization */
#else
} /* namespace multi_index::detail */
} /* namespace multi_index */
#endif
#endif
@@ -0,0 +1,93 @@
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP
#define BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mp11/utility.hpp>
#include <boost/tuple/tuple.hpp>
#include <tuple>
namespace boost{
namespace multi_index{
namespace detail{
/* std::tuple wrapper providing the cons-based interface of boost::tuple for
* composite_key interoperability.
*/
template<typename StdTuple,std::size_t N>
struct cons_stdtuple;
struct cons_stdtuple_ctor_terminal
{
typedef boost::tuples::null_type result_type;
template<typename StdTuple>
static result_type create(const StdTuple&)
{
return boost::tuples::null_type();
}
};
template<typename StdTuple,std::size_t N>
struct cons_stdtuple_ctor_normal
{
typedef cons_stdtuple<StdTuple,N> result_type;
static result_type create(const StdTuple& t)
{
return result_type(t);
}
};
template<typename StdTuple,std::size_t N=0>
struct cons_stdtuple_ctor:
mp11::mp_if_c<
N<std::tuple_size<StdTuple>::value,
cons_stdtuple_ctor_normal<StdTuple,N>,
cons_stdtuple_ctor_terminal
>
{};
template<typename StdTuple,std::size_t N>
struct cons_stdtuple
{
typedef typename std::tuple_element<N,StdTuple>::type head_type;
typedef cons_stdtuple_ctor<StdTuple,N+1> tail_ctor;
typedef typename tail_ctor::result_type tail_type;
cons_stdtuple(const StdTuple& t_):t(t_){}
const head_type& get_head()const{return std::get<N>(t);}
tail_type get_tail()const{return tail_ctor::create(t);}
const StdTuple& t;
};
template<typename StdTuple>
typename cons_stdtuple_ctor<StdTuple>::result_type
make_cons_stdtuple(const StdTuple& t)
{
return cons_stdtuple_ctor<StdTuple>::create(t);
}
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP
#define BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
@@ -31,13 +31,15 @@ struct converter
static Index& index(MultiIndexContainer& x){return x;}
static typename Index::const_iterator const_iterator(
const MultiIndexContainer& x,typename MultiIndexContainer::node_type* node)
const MultiIndexContainer& x,
typename MultiIndexContainer::final_node_type* node)
{
return x.Index::make_iterator(node);
}
static typename Index::iterator iterator(
MultiIndexContainer& x,typename MultiIndexContainer::node_type* node)
MultiIndexContainer& x,
typename MultiIndexContainer::final_node_type* node)
{
return x.Index::make_iterator(node);
}
+71 -38
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,17 +9,20 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
#define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
#include <boost/noncopyable.hpp>
#include <cstddef>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <functional>
#include <utility>
namespace boost{
@@ -53,14 +56,30 @@ struct copy_map_entry
}
};
struct copy_map_value_copier
{
template<typename Value>
const Value& operator()(Value& x)const{return x;}
};
struct copy_map_value_mover
{
template<typename Value>
Value&& operator()(Value& x)const{return std::move(x);}
};
template <typename Node,typename Allocator>
class copy_map:private noncopyable
{
typedef allocator_rebind_t<Allocator,Node> allocator_type;
typedef allocator_pointer_t<allocator_type> pointer;
public:
typedef const copy_map_entry<Node>* const_iterator;
typedef const copy_map_entry<Node>* const_iterator;
typedef allocator_size_type_t<allocator_type> size_type;
copy_map(
const Allocator& al,std::size_t size,Node* header_org,Node* header_cpy):
const Allocator& al,size_type size,Node* header_org,Node* header_cpy):
al_(al),size_(size),spc(al_,size_),n(0),
header_org_(header_org),header_cpy_(header_cpy),released(false)
{}
@@ -68,33 +87,19 @@ public:
~copy_map()
{
if(!released){
for(std::size_t i=0;i<n;++i){
boost::detail::allocator::destroy(&spc.data()[i].second->value);
deallocate(spc.data()[i].second);
for(size_type i=0;i<n;++i){
allocator_destroy(
al_,boost::addressof((spc.data()+i)->second->value()));
deallocate((spc.data()+i)->second);
}
}
}
const_iterator begin()const{return spc.data();}
const_iterator end()const{return spc.data()+n;}
const_iterator begin()const{return raw_ptr<const_iterator>(spc.data());}
const_iterator end()const{return raw_ptr<const_iterator>(spc.data()+n);}
void clone(Node* node)
{
spc.data()[n].first=node;
spc.data()[n].second=al_.allocate(1);
BOOST_TRY{
boost::detail::allocator::construct(
&spc.data()[n].second->value,node->value);
}
BOOST_CATCH(...){
deallocate(spc.data()[n].second);
BOOST_RETHROW;
}
BOOST_CATCH_END
++n;
if(n==size_)std::sort(spc.data(),spc.data()+size_);
}
void copy_clone(Node* node){clone(node,copy_map_value_copier());}
void move_clone(Node* node){clone(node,copy_map_value_mover());}
Node* find(Node* node)const
{
@@ -109,18 +114,46 @@ public:
}
private:
typename boost::detail::allocator::rebind_to<
Allocator,Node>::type al_;
std::size_t size_;
auto_space<copy_map_entry<Node>,Allocator> spc;
std::size_t n;
Node* header_org_;
Node* header_cpy_;
bool released;
allocator_type al_;
size_type size_;
auto_space<copy_map_entry<Node>,Allocator> spc;
size_type n;
Node* header_org_;
Node* header_cpy_;
bool released;
pointer allocate()
{
return allocator_allocate(al_,1);
}
void deallocate(Node* node)
{
al_.deallocate(node,1);
allocator_deallocate(al_,static_cast<pointer>(node),1);
}
template<typename ValueAccess>
void clone(Node* node,ValueAccess access)
{
(spc.data()+n)->first=node;
(spc.data()+n)->second=raw_ptr<Node*>(allocate());
BOOST_TRY{
allocator_construct(
al_,boost::addressof((spc.data()+n)->second->value()),
access(node->value()));
}
BOOST_CATCH(...){
deallocate((spc.data()+n)->second);
BOOST_RETHROW;
}
BOOST_CATCH_END
++n;
if(n==size_){
std::sort(
raw_ptr<copy_map_entry<Node>*>(spc.data()),
raw_ptr<copy_map_entry<Node>*>(spc.data())+size_);
}
}
};
@@ -1,59 +0,0 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_DEF_CTOR_TUPLE_CONS_HPP
#define BOOST_MULTI_INDEX_DETAIL_DEF_CTOR_TUPLE_CONS_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
/* In MSVC, tuples::cons is not default constructible. We provide a
* tiny wrapper around tuple::cons filling that hole.
*/
#include <boost/tuple/tuple.hpp>
namespace boost{
namespace multi_index{
namespace detail{
template<typename Cons>
struct default_constructible_tuple_cons:Cons
{
default_constructible_tuple_cons():
Cons(
Cons::head_type(),
static_cast<const Cons::tail_type&>(
default_constructible_tuple_cons<Cons::tail_type>()))
{}
default_constructible_tuple_cons(const Cons& cons):Cons(cons){}
};
template<>
struct default_constructible_tuple_cons<tuples::null_type>:tuples::null_type
{
default_constructible_tuple_cons(){}
default_constructible_tuple_cons(const tuples::null_type&){}
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif /* BOOST_MSVC */
#endif
@@ -0,0 +1,34 @@
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#if !defined(BOOST_CONFIG_HPP)
#error <boost/config.hpp> must be included before this header
#endif
#if !defined(BOOST_MULTI_INDEX_DETAIL_UNDEF_IF_CONSTEXPR_MACRO)
#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR)
#define BOOST_MULTI_INDEX_IF_CONSTEXPR if constexpr
#else
#define BOOST_MULTI_INDEX_IF_CONSTEXPR if
#if defined(BOOST_MSVC)
#define BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED
#pragma warning(push)
#pragma warning(disable:4127) /* conditional expression is constant */
#endif
#endif
#else
#undef BOOST_MULTI_INDEX_IF_CONSTEXPR
#if defined(BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED)
#pragma warning(pop)
#undef BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED
#endif
#endif
@@ -0,0 +1,34 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP
#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* Used to mark a special ctor variant that copies the internal objects of
* a container but not its elements.
*/
struct do_not_copy_elements_tag{};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,12 +9,11 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <cstddef>
#include <iterator>
namespace boost{
@@ -32,30 +31,30 @@ class duplicates_iterator
{
public:
typedef typename Node::value_type value_type;
typedef std::ptrdiff_t difference_type;
typedef typename Node::difference_type difference_type;
typedef const typename Node::value_type* pointer;
typedef const typename Node::value_type& reference;
typedef std::forward_iterator_tag iterator_category;
duplicates_iterator(Node* node,Node* end,Predicate pred):
node(node),begin_chunk(0),end(end),pred(pred)
duplicates_iterator(Node* node_,Node* end_,Predicate pred_):
node(node_),begin_chunk(0),end(end_),pred(pred_)
{
advance();
}
duplicates_iterator(Node* end,Predicate pred):
node(end),begin_chunk(end),end(end),pred(pred)
duplicates_iterator(Node* end_,Predicate pred_):
node(end_),begin_chunk(end_),end(end_),pred(pred_)
{
}
reference operator*()const
{
return node->value;
return node->value();
}
pointer operator->()const
{
return node->value;
return &node->value();
}
duplicates_iterator& operator++()
@@ -77,15 +76,14 @@ public:
private:
void sync()
{
if(pred(begin_chunk->value,node->value))advance();
if(node!=end&&pred(begin_chunk->value(),node->value()))advance();
}
void advance()
{
for(Node* node2=node;node!=end;node=node2){
Node::increment(node2);
if(node2!=end&&!pred(node->value,node2->value))break;
node=node2;
if(node2!=end&&!pred(node->value(),node2->value()))break;
}
begin_chunk=node;
}
+5 -7
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,12 +9,12 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP
#define BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/contains.hpp>
#include <boost/mp11/algorithm.hpp>
namespace boost{
@@ -28,9 +28,7 @@ template<typename Tag>
struct has_tag
{
template<typename Index>
struct apply:mpl::contains<BOOST_DEDUCED_TYPENAME Index::tag_list,Tag>
{
};
using fn=mp11::mp_contains<typename Index::tag_list,Tag>;
};
} /* namespace multi_index::detail */
@@ -39,4 +37,4 @@ struct has_tag
} /* namespace boost */
#endif
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,25 +9,21 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/functional/hash/hash.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <functional>
#include <type_traits>
namespace boost{
template<class T> struct hash; /* fwd decl. */
namespace multi_index{
namespace detail{
@@ -48,54 +44,44 @@ namespace detail{
* argument-dependent polymorphism.
*/
template<typename KeyFromValue>
struct index_args_default_hash
{
typedef ::boost::hash<typename KeyFromValue::result_type> type;
};
template<typename KeyFromValue>
struct index_args_default_pred
{
typedef std::equal_to<typename KeyFromValue::result_type> type;
};
template<typename Arg1,typename Arg2,typename Arg3,typename Arg4>
struct hashed_index_args
{
typedef is_tag<Arg1> full_form;
typedef typename mpl::if_<
typedef mp11::mp_if<
full_form,
Arg1,
tag< > >::type tag_list_type;
typedef typename mpl::if_<
tag< > > tag_list_type;
typedef mp11::mp_if<
full_form,
Arg2,
Arg1>::type key_from_value_type;
typedef typename mpl::if_<
Arg1> key_from_value_type;
typedef mp11::mp_if<
full_form,
Arg3,
Arg2>::type supplied_hash_type;
typedef typename mpl::eval_if<
mpl::is_na<supplied_hash_type>,
index_args_default_hash<key_from_value_type>,
mpl::identity<supplied_hash_type>
>::type hash_type;
typedef typename mpl::if_<
Arg2> supplied_hash_type;
typedef mp11::mp_eval_if_c<
!std::is_void<supplied_hash_type>::value,
supplied_hash_type,
boost::hash,
typename key_from_value_type::result_type
> hash_type;
typedef mp11::mp_if<
full_form,
Arg4,
Arg3>::type supplied_pred_type;
typedef typename mpl::eval_if<
mpl::is_na<supplied_pred_type>,
index_args_default_pred<key_from_value_type>,
mpl::identity<supplied_pred_type>
>::type pred_type;
Arg3> supplied_pred_type;
typedef mp11::mp_eval_if_c<
!std::is_void<supplied_pred_type>::value,
supplied_pred_type,
std::equal_to,
typename key_from_value_type::result_type
> pred_type;
BOOST_STATIC_ASSERT(is_tag<tag_list_type>::value);
BOOST_STATIC_ASSERT(!mpl::is_na<key_from_value_type>::value);
BOOST_STATIC_ASSERT(!mpl::is_na<hash_type>::value);
BOOST_STATIC_ASSERT(!mpl::is_na<pred_type>::value);
BOOST_STATIC_ASSERT(!std::is_void<key_from_value_type>::value);
BOOST_STATIC_ASSERT(!std::is_void<hash_type>::value);
BOOST_STATIC_ASSERT(!std::is_void<pred_type>::value);
};
} /* namespace multi_index::detail */
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2026 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,19 +9,16 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#include <boost/multi_index/detail/hash_index_proxy.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <boost/operators.hpp>
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/core/serialization.hpp>
#endif
namespace boost{
@@ -30,148 +27,156 @@ namespace multi_index{
namespace detail{
/* An iterator template for nodes of multi_index::detail::hashed_index.
* Built with the aid boost::forward_iterator_helper from
* boost/operators.hpp.
/* Iterator class for hashed indices.
*/
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
template<typename Node,typename BucketArray>
struct hashed_index_global_iterator_tag{};
struct hashed_index_local_iterator_tag{};
template<
typename Node,typename BucketArray,
typename IndexCategory,typename IteratorCategory
>
class hashed_index_iterator:
public boost::forward_iterator_helper<
hashed_index_iterator<Node,BucketArray>,
public forward_iterator_helper<
hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory>,
typename Node::value_type,
std::ptrdiff_t,
const typename Node::value_type*,
const typename Node::value_type&>,
public safe_iterator<hashed_index_proxy<Node,BucketArray> >
#else
template<typename Node,typename BucketArray,typename Container>
class hashed_index_iterator:
public boost::forward_iterator_helper<
hashed_index_iterator<Node,BucketArray,Container>,
typename Node::value_type,
std::ptrdiff_t,
const typename Node::value_type*,
const typename Node::value_type&>,
public safe_iterator<Container>
#endif
#else
template<typename Node,typename BucketArray>
class hashed_index_iterator:
public boost::forward_iterator_helper<
hashed_index_iterator<Node,BucketArray>,
typename Node::value_type,
std::ptrdiff_t,
typename Node::difference_type,
const typename Node::value_type*,
const typename Node::value_type&>
#endif
{
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
public:
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
typedef hashed_index_proxy<Node,BucketArray> container_type;
#else
typedef Container container_type;
#endif
private:
typedef safe_iterator<container_type> safe_super;
public:
hashed_index_iterator():node(0),buckets(0){}
hashed_index_iterator(
Node* node_,BucketArray& buckets_,container_type* cont_):
safe_super(cont_),node(node_),buckets(&buckets_){}
hashed_index_iterator& operator=(const hashed_index_iterator& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x);
safe_super::operator=(x);
node=x.node;
buckets=x.buckets;
return *this;
}
#else
public:
/* coverity[uninit_ctor]: suppress warning */
hashed_index_iterator(){}
hashed_index_iterator(Node* node_,BucketArray& buckets_):
node(node_),buckets(&buckets_){}
#endif
hashed_index_iterator(Node* node_):node(node_){}
const typename Node::value_type& operator*()const
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this);
return node->value;
return node->value();
}
hashed_index_iterator& operator++()
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this);
Node::increment(node,buckets->begin(),buckets->end());
this->increment(IteratorCategory());
return *this;
}
friend bool operator==(const hashed_index_iterator& x,const hashed_index_iterator& y)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x);
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(y);
BOOST_MULTI_INDEX_CHECK_SAME_OWNER(x,y);
return x.node==y.node;
}
/* get_node is not to be used by the user */
Node* get_node()const{return node;}
private:
Node* node;
BucketArray* buckets;
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
/* serialization */
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
/* Serialization. As for why the following is public,
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
*/
template<class Archive>
void serialize(Archive& ar,const unsigned int version)
{
core::split_member(ar,*this,version);
}
typedef typename Node::base_type node_base_type;
template<class Archive>
void save(Archive& ar,const unsigned int version)const
void save(Archive& ar,const unsigned int)const
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
node_base_type* bnode=node;
ar<<serialization::make_nvp("pointer",bnode);
ar<<serialization::make_nvp("pointer",buckets);
node_base_type* bnode=get_node();
ar<<core::make_nvp("pointer",bnode);
}
template<class Archive>
void load(Archive& ar,const unsigned int version)
{
load(ar,version,IteratorCategory());
}
template<class Archive>
void load(
Archive& ar,const unsigned int version,hashed_index_global_iterator_tag)
{
node_base_type* bnode;
ar>>serialization::make_nvp("pointer",bnode);
node=static_cast<Node*>(bnode);
ar>>serialization::make_nvp("pointer",buckets);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::uncheck();
#endif
ar>>core::make_nvp("pointer",bnode);
node=typename Node::pointer(static_cast<Node*>(bnode));
if(version<1){
BucketArray* throw_away; /* consume unused ptr */
ar>>core::make_nvp("pointer",throw_away);
}
}
template<class Archive>
void load(
Archive& ar,const unsigned int version,hashed_index_local_iterator_tag)
{
node_base_type* bnode;
ar>>core::make_nvp("pointer",bnode);
node=typename Node::pointer(static_cast<Node*>(bnode));
if(version<1){
BucketArray* buckets;
ar>>core::make_nvp("pointer",buckets);
if(buckets&&bnode&&node->impl()==buckets->end()->prior()){
/* end local_iterators used to point to end node, now they are null */
node=typename Node::pointer(0);
}
}
}
#endif
/* get_node is not to be used by the user */
typedef Node node_type;
Node* get_node()const{return raw_ptr<Node*>(node);}
private:
void increment(hashed_index_global_iterator_tag)
{
Node::template increment<IndexCategory>(node);
}
void increment(hashed_index_local_iterator_tag)
{
Node::template increment_local<IndexCategory>(node);
}
typename Node::pointer node;
};
template<
typename Node,typename BucketArray,
typename IndexCategory,typename IteratorCategory
>
bool operator==(
const hashed_index_iterator<
Node,BucketArray,IndexCategory,IteratorCategory>& x,
const hashed_index_iterator<
Node,BucketArray,IndexCategory,IteratorCategory>& y)
{
return x.get_node()==y.get_node();
}
} /* namespace multi_index::detail */
} /* namespace multi_index */
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
/* class version = 1 : hashed_index_iterator does no longer serialize a bucket
* array pointer.
*/
namespace serialization {
template<
typename Node,typename BucketArray,
typename IndexCategory,typename IteratorCategory
>
struct version<
boost::multi_index::detail::hashed_index_iterator<
Node,BucketArray,IndexCategory,IteratorCategory
>
>
{
BOOST_STATIC_CONSTANT(int,value=1);
};
} /* namespace serialization */
#endif
} /* namespace boost */
#endif
@@ -1,44 +0,0 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_FWD_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_FWD_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
namespace boost{
namespace multi_index{
namespace detail{
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
template<typename Node,typename BucketArray>
class hashed_index_iterator;
#else
template<typename Node,typename BucketArray,typename Container>
class hashed_index_iterator;
#endif
#else
template<typename Node,typename BucketArray>
class hashed_index_iterator;
#endif
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2026 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,12 +9,14 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <functional>
#include <boost/core/allocator_access.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <utility>
namespace boost{
@@ -22,107 +24,753 @@ namespace multi_index{
namespace detail{
/* singly-linked node for use by hashed_index */
/* Certain C++ requirements on unordered associative containers (see LWG issue
* #579) imply a data structure where nodes are linked in a single list, which
* in its turn forces implementors to add additional overhed per node to
* associate each with its corresponding bucket. Others resort to storing hash
* values, we use an alternative structure providing unconditional O(1)
* manipulation, even in situations of unfair hash distribution, plus some
* lookup speedups. For unique indices we maintain a doubly linked list of
* nodes except that if N is the first node of a bucket its associated
* bucket node is embedded between N and the preceding node in the following
* manner:
*
* +---+ +---+ +---+ +---+
* <--+ |<--+ | <--+ |<--+ |
* ... | B0| | B1| ... | B1| | B2| ...
* | |-+ | +--> | |-+ | +-->
* +-+-+ | +---+ +-+-+ | +---+
* | ^ | ^
* | | | |
* | +-+ | +-+
* | | | |
* v | v |
* --+---+---+---+-- --+---+---+---+--
* ... | | B1| | ... | | B2| | ...
* --+---+---+---+-- --+---+---+---+--
*
*
* The fist and last nodes of buckets can be checked with
*
* first node of a bucket: Npn != N
* last node of a bucket: Nnp != N
*
* (n and p short for ->next(), ->prior(), bucket nodes have prior pointers
* only). Pure insert and erase (without lookup) can be unconditionally done
* in O(1).
* For non-unique indices we add the following additional complexity: when
* there is a group of 3 or more equivalent elements, they are linked as
* follows:
*
* +-----------------------+
* | v
* +---+ | +---+ +---+ +---+
* | | +-+ | | |<--+ |
* | F | | S | ... | P | | L |
* | +-->| | | +-+ | |
* +---+ +---+ +---+ | +---+
* ^ |
* +-----------------------+
*
* F, S, P and L are the first, second, penultimate and last node in the
* group, respectively (S and P can coincide if the group has size 3.) This
* arrangement is used to skip equivalent elements in O(1) when doing lookup,
* while preserving O(1) insert/erase. The following invariants identify
* special positions (some of the operations have to be carefully implemented
* as Xnn is not valid if Xn points to a bucket):
*
* first node of a bucket: Npnp == N
* last node of a bucket: Nnpp == N
* first node of a group: Nnp != N && Nnppn == N
* second node of a group: Npn != N && Nppnn == N
* n-1 node of a group: Nnp != N && Nnnpp == N
* last node of a group: Npn != N && Npnnp == N
*
* The memory overhead is one pointer per bucket plus two pointers per node,
* probably unbeatable. The resulting structure is bidirectonally traversable,
* though currently we are just providing forward iteration.
*/
struct hashed_index_node_impl
template<typename Allocator>
struct hashed_index_node_impl;
/* half-header (only prior() pointer) to use for the bucket array */
template<typename Allocator>
struct hashed_index_base_node_impl
{
hashed_index_node_impl*& next(){return next_;}
hashed_index_node_impl*const & next()const{return next_;}
typedef allocator_rebind_t<
Allocator,hashed_index_base_node_impl
> base_allocator;
typedef allocator_rebind_t<
Allocator,hashed_index_node_impl<Allocator>
> node_allocator;
typedef allocator_pointer_t<base_allocator> base_pointer;
typedef allocator_const_pointer_t<base_allocator> const_base_pointer;
typedef allocator_pointer_t<node_allocator> pointer;
typedef allocator_const_pointer_t<node_allocator> const_pointer;
typedef allocator_difference_type_t<node_allocator> difference_type;
/* interoperability with hashed_index_proxy */
pointer& prior(){return prior_;}
pointer prior()const{return prior_;}
static hashed_index_node_impl* end(hashed_index_node_impl* header)
private:
pointer prior_;
};
/* full header (prior() and next()) for the nodes */
template<typename Allocator>
struct hashed_index_node_impl:hashed_index_base_node_impl<Allocator>
{
private:
typedef hashed_index_base_node_impl<Allocator> super;
public:
typedef typename super::base_pointer base_pointer;
typedef typename super::const_base_pointer const_base_pointer;
typedef typename super::pointer pointer;
typedef typename super::const_pointer const_pointer;
base_pointer& next(){return next_;}
base_pointer next()const{return next_;}
static pointer pointer_from(base_pointer x)
{
return header;
return static_cast<pointer>(
static_cast<hashed_index_node_impl*>(
raw_ptr<super*>(x)));
}
/* algorithmic stuff */
static void increment(
hashed_index_node_impl*& x,
hashed_index_node_impl* bbegin,hashed_index_node_impl* bbend)
static base_pointer base_pointer_from(pointer x)
{
std::less_equal<hashed_index_node_impl*> leq;
return static_cast<base_pointer>(
raw_ptr<hashed_index_node_impl*>(x));
}
x=x->next();
if(leq(bbegin,x)&&leq(x,bbend)){ /* bucket node */
do{
++x;
}while(x->next()==x);
x=x->next();
private:
base_pointer next_;
};
/* Boost.MultiIndex requires machinery to reverse unlink operations. A simple
* way to make a pointer-manipulation function undoable is to templatize
* its internal pointer assignments with a functor that, besides doing the
* assignment, keeps track of the original pointer values and can later undo
* the operations in reverse order.
*/
struct default_assigner
{
template<typename T> void operator()(T& x,const T& val){x=val;}
};
template<typename Node>
struct unlink_undo_assigner
{
typedef typename Node::base_pointer base_pointer;
typedef typename Node::pointer pointer;
unlink_undo_assigner():pointer_track_count(0),base_pointer_track_count(0){}
void operator()(pointer& x,pointer val)
{
pointer_tracks[pointer_track_count].x=&x;
pointer_tracks[pointer_track_count++].val=x;
x=val;
}
void operator()(base_pointer& x,base_pointer val)
{
base_pointer_tracks[base_pointer_track_count].x=&x;
base_pointer_tracks[base_pointer_track_count++].val=x;
x=val;
}
void operator()() /* undo op */
{
/* in the absence of aliasing, restitution order is immaterial */
while(pointer_track_count--){
*(pointer_tracks[pointer_track_count].x)=
pointer_tracks[pointer_track_count].val;
}
while(base_pointer_track_count--){
*(base_pointer_tracks[base_pointer_track_count].x)=
base_pointer_tracks[base_pointer_track_count].val;
}
}
static void link(
hashed_index_node_impl* x,hashed_index_node_impl* pos)
{
x->next()=pos->next();
pos->next()=x;
};
struct pointer_track {pointer* x; pointer val;};
struct base_pointer_track{base_pointer* x; base_pointer val;};
static void unlink(hashed_index_node_impl* x)
/* We know the maximum number of pointer and base pointer assignments that
* the two unlink versions do, so we can statically reserve the needed
* storage.
*/
pointer_track pointer_tracks[3];
int pointer_track_count;
base_pointer_track base_pointer_tracks[2];
int base_pointer_track_count;
};
/* algorithmic stuff for unique and non-unique variants */
struct hashed_unique_tag{};
struct hashed_non_unique_tag{};
template<typename Node,typename Category>
struct hashed_index_node_alg;
template<typename Node>
struct hashed_index_node_alg<Node,hashed_unique_tag>
{
typedef typename Node::base_pointer base_pointer;
typedef typename Node::const_base_pointer const_base_pointer;
typedef typename Node::pointer pointer;
typedef typename Node::const_pointer const_pointer;
static bool is_first_of_bucket(pointer x)
{
hashed_index_node_impl* y=x->next();
while(y->next()!=x){y=y->next();}
y->next()=x->next();
return x->prior()->next()!=base_pointer_from(x);
}
static hashed_index_node_impl* prev(hashed_index_node_impl* x)
static pointer after(pointer x)
{
hashed_index_node_impl* y=x->next();
while(y->next()!=x){y=y->next();}
return y;
return is_last_of_bucket(x)?x->next()->prior():pointer_from(x->next());
}
static void unlink_next(hashed_index_node_impl* x)
static pointer after_local(pointer x)
{
x->next()=x->next()->next();
return is_last_of_bucket(x)?pointer(0):pointer_from(x->next());
}
static pointer next_to_inspect(pointer x)
{
return is_last_of_bucket(x)?pointer(0):pointer_from(x->next());
}
static void link(pointer x,base_pointer buc,pointer end)
{
if(buc->prior()==pointer(0)){ /* empty bucket */
x->prior()=end->prior();
x->next()=end->prior()->next();
x->prior()->next()=buc;
buc->prior()=x;
end->prior()=x;
}
else{
x->prior()=buc->prior()->prior();
x->next()=base_pointer_from(buc->prior());
buc->prior()=x;
x->next()->prior()=x;
}
}
static void unlink(pointer x)
{
default_assigner assign;
unlink(x,assign);
}
typedef unlink_undo_assigner<Node> unlink_undo;
template<typename Assigner>
static void unlink(pointer x,Assigner& assign)
{
if(is_first_of_bucket(x)){
if(is_last_of_bucket(x)){
assign(x->prior()->next()->prior(),pointer(0));
assign(x->prior()->next(),x->next());
assign(x->next()->prior()->prior(),x->prior());
}
else{
assign(x->prior()->next()->prior(),pointer_from(x->next()));
assign(x->next()->prior(),x->prior());
}
}
else if(is_last_of_bucket(x)){
assign(x->prior()->next(),x->next());
assign(x->next()->prior()->prior(),x->prior());
}
else{
assign(x->prior()->next(),x->next());
assign(x->next()->prior(),x->prior());
}
}
/* used only at rehashing */
static void append(pointer x,pointer end)
{
x->prior()=end->prior();
x->next()=end->prior()->next();
x->prior()->next()=base_pointer_from(x);
end->prior()=x;
}
static bool unlink_last(pointer end)
{
/* returns true iff bucket is emptied */
pointer x=end->prior();
if(x->prior()->next()==base_pointer_from(x)){
x->prior()->next()=x->next();
end->prior()=x->prior();
return false;
}
else{
x->prior()->next()->prior()=pointer(0);
x->prior()->next()=x->next();
end->prior()=x->prior();
return true;
}
}
private:
hashed_index_node_impl();
static pointer pointer_from(base_pointer x)
{
return Node::pointer_from(x);
}
hashed_index_node_impl* next_;
static base_pointer base_pointer_from(pointer x)
{
return Node::base_pointer_from(x);
}
static bool is_last_of_bucket(pointer x)
{
return x->next()->prior()!=x;
}
};
template<typename Node>
struct hashed_index_node_alg<Node,hashed_non_unique_tag>
{
typedef typename Node::base_pointer base_pointer;
typedef typename Node::const_base_pointer const_base_pointer;
typedef typename Node::pointer pointer;
typedef typename Node::const_pointer const_pointer;
static bool is_first_of_bucket(pointer x)
{
return x->prior()->next()->prior()==x;
}
static bool is_first_of_group(pointer x)
{
return
x->next()->prior()!=x&&
x->next()->prior()->prior()->next()==base_pointer_from(x);
}
static pointer after(pointer x)
{
if(x->next()->prior()==x)return pointer_from(x->next());
if(x->next()->prior()->prior()==x)return x->next()->prior();
if(x->next()->prior()->prior()->next()==base_pointer_from(x))
return pointer_from(x->next());
return pointer_from(x->next())->next()->prior();
}
static pointer after_local(pointer x)
{
if(x->next()->prior()==x)return pointer_from(x->next());
if(x->next()->prior()->prior()==x)return pointer(0);
if(x->next()->prior()->prior()->next()==base_pointer_from(x))
return pointer_from(x->next());
return pointer_from(x->next())->next()->prior();
}
static pointer next_to_inspect(pointer x)
{
if(x->next()->prior()==x)return pointer_from(x->next());
if(x->next()->prior()->prior()==x)return pointer(0);
if(x->next()->prior()->next()->prior()!=x->next()->prior())
return pointer(0);
return pointer_from(x->next()->prior()->next());
}
static void link(pointer x,base_pointer buc,pointer end)
{
if(buc->prior()==pointer(0)){ /* empty bucket */
x->prior()=end->prior();
x->next()=end->prior()->next();
x->prior()->next()=buc;
buc->prior()=x;
end->prior()=x;
}
else{
x->prior()=buc->prior()->prior();
x->next()=base_pointer_from(buc->prior());
buc->prior()=x;
x->next()->prior()=x;
}
}
static void link(pointer x,pointer first,pointer last)
{
x->prior()=first->prior();
x->next()=base_pointer_from(first);
if(is_first_of_bucket(first)){
x->prior()->next()->prior()=x;
}
else{
x->prior()->next()=base_pointer_from(x);
}
if(first==last){
last->prior()=x;
}
else if(first->next()==base_pointer_from(last)){
first->prior()=last;
first->next()=base_pointer_from(x);
}
else{
pointer second=pointer_from(first->next()),
lastbutone=last->prior();
second->prior()=first;
first->prior()=last;
lastbutone->next()=base_pointer_from(x);
}
}
static void unlink(pointer x)
{
default_assigner assign;
unlink(x,assign);
}
typedef unlink_undo_assigner<Node> unlink_undo;
template<typename Assigner>
static void unlink(pointer x,Assigner& assign)
{
if(x->prior()->next()==base_pointer_from(x)){
if(x->next()->prior()==x){
left_unlink(x,assign);
right_unlink(x,assign);
}
else if(x->next()->prior()->prior()==x){ /* last of bucket */
left_unlink(x,assign);
right_unlink_last_of_bucket(x,assign);
}
else if(x->next()->prior()->prior()->next()==
base_pointer_from(x)){ /* first of group size */
left_unlink(x,assign);
right_unlink_first_of_group(x,assign);
}
else{ /* n-1 of group */
unlink_last_but_one_of_group(x,assign);
}
}
else if(x->prior()->next()->prior()==x){ /* first of bucket */
if(x->next()->prior()==x){
left_unlink_first_of_bucket(x,assign);
right_unlink(x,assign);
}
else if(x->next()->prior()->prior()==x){ /* last of bucket */
assign(x->prior()->next()->prior(),pointer(0));
assign(x->prior()->next(),x->next());
assign(x->next()->prior()->prior(),x->prior());
}
else{ /* first of group */
left_unlink_first_of_bucket(x,assign);
right_unlink_first_of_group(x,assign);
}
}
else if(x->next()->prior()->prior()==x){ /* last of group and bucket */
left_unlink_last_of_group(x,assign);
right_unlink_last_of_bucket(x,assign);
}
else if(pointer_from(x->prior()->prior()->next())
->next()==base_pointer_from(x)){ /* second of group */
unlink_second_of_group(x,assign);
}
else{ /* last of group, ~(last of bucket) */
left_unlink_last_of_group(x,assign);
right_unlink(x,assign);
}
}
/* used only at rehashing */
static void link_range(
pointer first,pointer last,base_pointer buc,pointer cend)
{
if(buc->prior()==pointer(0)){ /* empty bucket */
first->prior()=cend->prior();
last->next()=cend->prior()->next();
first->prior()->next()=buc;
buc->prior()=first;
cend->prior()=last;
}
else{
first->prior()=buc->prior()->prior();
last->next()=base_pointer_from(buc->prior());
buc->prior()=first;
last->next()->prior()=last;
}
}
static void append_range(pointer first,pointer last,pointer cend)
{
first->prior()=cend->prior();
last->next()=cend->prior()->next();
first->prior()->next()=base_pointer_from(first);
cend->prior()=last;
}
static std::pair<pointer,bool> unlink_last_group(pointer end)
{
/* returns first of group true iff bucket is emptied */
pointer x=end->prior();
if(x->prior()->next()==base_pointer_from(x)){
x->prior()->next()=x->next();
end->prior()=x->prior();
return std::make_pair(x,false);
}
else if(x->prior()->next()->prior()==x){
x->prior()->next()->prior()=pointer(0);
x->prior()->next()=x->next();
end->prior()=x->prior();
return std::make_pair(x,true);
}
else{
pointer y=pointer_from(x->prior()->next());
if(y->prior()->next()==base_pointer_from(y)){
y->prior()->next()=x->next();
end->prior()=y->prior();
return std::make_pair(y,false);
}
else{
y->prior()->next()->prior()=pointer(0);
y->prior()->next()=x->next();
end->prior()=y->prior();
return std::make_pair(y,true);
}
}
}
static void unlink_range(pointer first,pointer last)
{
if(is_first_of_bucket(first)){
if(is_last_of_bucket(last)){
first->prior()->next()->prior()=pointer(0);
first->prior()->next()=last->next();
last->next()->prior()->prior()=first->prior();
}
else{
first->prior()->next()->prior()=pointer_from(last->next());
last->next()->prior()=first->prior();
}
}
else if(is_last_of_bucket(last)){
first->prior()->next()=last->next();
last->next()->prior()->prior()=first->prior();
}
else{
first->prior()->next()=last->next();
last->next()->prior()=first->prior();
}
}
private:
static pointer pointer_from(base_pointer x)
{
return Node::pointer_from(x);
}
static base_pointer base_pointer_from(pointer x)
{
return Node::base_pointer_from(x);
}
static bool is_last_of_bucket(pointer x)
{
return x->next()->prior()->prior()==x;
}
template<typename Assigner>
static void left_unlink(pointer x,Assigner& assign)
{
assign(x->prior()->next(),x->next());
}
template<typename Assigner>
static void right_unlink(pointer x,Assigner& assign)
{
assign(x->next()->prior(),x->prior());
}
template<typename Assigner>
static void left_unlink_first_of_bucket(pointer x,Assigner& assign)
{
assign(x->prior()->next()->prior(),pointer_from(x->next()));
}
template<typename Assigner>
static void right_unlink_last_of_bucket(pointer x,Assigner& assign)
{
assign(x->next()->prior()->prior(),x->prior());
}
template<typename Assigner>
static void right_unlink_first_of_group(pointer x,Assigner& assign)
{
pointer second=pointer_from(x->next()),
last=second->prior(),
lastbutone=last->prior();
if(second==lastbutone){
assign(second->next(),base_pointer_from(last));
assign(second->prior(),x->prior());
}
else{
assign(lastbutone->next(),base_pointer_from(second));
assign(second->next()->prior(),last);
assign(second->prior(),x->prior());
}
}
template<typename Assigner>
static void left_unlink_last_of_group(pointer x,Assigner& assign)
{
pointer lastbutone=x->prior(),
first=pointer_from(lastbutone->next()),
second=pointer_from(first->next());
if(lastbutone==second){
assign(lastbutone->prior(),first);
assign(lastbutone->next(),x->next());
}
else{
assign(second->prior(),lastbutone);
assign(lastbutone->prior()->next(),base_pointer_from(first));
assign(lastbutone->next(),x->next());
}
}
template<typename Assigner>
static void unlink_last_but_one_of_group(pointer x,Assigner& assign)
{
pointer first=pointer_from(x->next()),
second=pointer_from(first->next()),
last=second->prior();
if(second==x){
assign(last->prior(),first);
assign(first->next(),base_pointer_from(last));
}
else{
assign(last->prior(),x->prior());
assign(x->prior()->next(),base_pointer_from(first));
}
}
template<typename Assigner>
static void unlink_second_of_group(pointer x,Assigner& assign)
{
pointer last=x->prior(),
lastbutone=last->prior(),
first=pointer_from(lastbutone->next());
if(lastbutone==x){
assign(first->next(),base_pointer_from(last));
assign(last->prior(),first);
}
else{
assign(first->next(),x->next());
assign(x->next()->prior(),last);
}
}
};
template<typename Super>
struct hashed_index_node_trampoline:hashed_index_node_impl{};
struct hashed_index_node_trampoline:
hashed_index_node_impl<
allocator_rebind_t<
typename Super::allocator_type,char
>
>
{
typedef allocator_rebind_t<
typename Super::allocator_type,char
> impl_allocator_type;
typedef hashed_index_node_impl<impl_allocator_type> impl_type;
};
template<typename Super>
struct hashed_index_node:Super,hashed_index_node_trampoline<Super>
struct hashed_index_node:
Super,hashed_index_node_trampoline<Super>
{
hashed_index_node_impl* impl()
{return static_cast<impl_type*>(this);}
const hashed_index_node_impl* impl()const
{return static_cast<const impl_type*>(this);}
static hashed_index_node* from_impl(hashed_index_node_impl *x)
{return static_cast<hashed_index_node*>(static_cast<impl_type*>(x));}
static const hashed_index_node* from_impl(
const hashed_index_node_impl* x)
{
return static_cast<const hashed_index_node*>(
static_cast<const impl_type*>(x));
}
static void increment(
hashed_index_node*& x,
hashed_index_node_impl* bbegin,hashed_index_node_impl* bend)
{
hashed_index_node_impl* xi=x->impl();
impl_type::increment(xi,bbegin,bend);
x=from_impl(xi);
}
/* interoperability with hashed_index_proxy */
static hashed_index_node* end(hashed_index_node* header)
{
return from_impl(impl_type::end(header->impl()));
}
private:
typedef hashed_index_node_trampoline<Super> impl_type;
typedef hashed_index_node_trampoline<Super> trampoline;
public:
typedef typename trampoline::impl_type impl_type;
typedef typename trampoline::base_pointer impl_base_pointer;
typedef typename trampoline::const_base_pointer const_impl_base_pointer;
typedef typename trampoline::pointer impl_pointer;
typedef typename trampoline::const_pointer const_impl_pointer;
typedef typename trampoline::difference_type difference_type;
typedef allocator_rebind_t<
typename trampoline::impl_allocator_type,
hashed_index_node> final_allocator_type;
typedef allocator_pointer_t<
final_allocator_type> pointer;
typedef allocator_const_pointer_t<
final_allocator_type> const_pointer;
template<typename Category>
struct node_alg{
typedef hashed_index_node_alg<impl_type,Category> type;
};
impl_pointer& prior(){return trampoline::prior();}
impl_pointer prior()const{return trampoline::prior();}
impl_base_pointer& next(){return trampoline::next();}
impl_base_pointer next()const{return trampoline::next();}
impl_pointer impl()
{
return static_cast<impl_pointer>(
static_cast<impl_type*>(static_cast<trampoline*>(this)));
}
const_impl_pointer impl()const
{
return static_cast<const_impl_pointer>(
static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
}
static hashed_index_node* from_impl(impl_pointer x)
{
return
static_cast<hashed_index_node*>(
static_cast<trampoline*>(
raw_ptr<impl_type*>(x)));
}
static const hashed_index_node* from_impl(const_impl_pointer x)
{
return
static_cast<const hashed_index_node*>(
static_cast<const trampoline*>(
raw_ptr<const impl_type*>(x)));
}
/* interoperability with hashed_index_iterator */
template<typename Category>
static void increment(pointer& x)
{
x=pointer(from_impl(node_alg<Category>::type::after(x->impl())));
}
template<typename Category>
static void increment_local(pointer& x)
{
x=pointer(from_impl(node_alg<Category>::type::after_local(x->impl())));
}
};
} /* namespace multi_index::detail */
@@ -1,75 +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)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_hashed_index_proxy_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_hashed_index_proxy_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
#include <algorithm>
#include <boost/multi_index/detail/hash_index_iterator_fwd.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
namespace boost{
namespace multi_index{
namespace detail{
/* Analogous of index_proxy for interoperability with
* hashed_index_iterator.
*/
template<typename Node,typename BucketArray>
class hashed_index_proxy:
public safe_container<hashed_index_proxy<Node,BucketArray> >
{
protected:
hashed_index_proxy(Node* header_,BucketArray& buckets_):
header(header_),buckets(&buckets_){}
void swap(hashed_index_proxy<Node,BucketArray>& x)
{
std::swap(header,x.header);
std::swap(buckets,x.buckets);
safe_container<hashed_index_proxy<Node,BucketArray> >::swap(x);
}
public:
typedef hashed_index_iterator<Node,BucketArray> iterator;
typedef hashed_index_iterator<Node,BucketArray> const_iterator;
hashed_index_iterator<Node,BucketArray> end()const
{
return hashed_index_iterator<Node,BucketArray>(
Node::end(header),*buckets,const_cast<hashed_index_proxy*>(this));
}
private:
Node* header;
BucketArray* buckets;
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif /* workaround */
#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,12 +9,11 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP
#define BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/noncopyable.hpp>
#include <boost/utility/base_from_member.hpp>
#include <boost/core/noncopyable.hpp>
namespace boost{
@@ -22,23 +21,23 @@ namespace multi_index{
namespace detail{
/* An utility class derived from base_from_member used to hold
* a pointer to the header node. The base from member idiom is used
* because index classes, which are superclasses of multi_index_container,
* need this header in construction time.
* The allocation is made by the allocator of the multi_index_container
/* A utility class used to hold a pointer to the header node.
* The base from member idiom is used because index classes, which are
* superclasses of multi_index_container, need this header in construction
* time. The allocation is made by the allocator of the multi_index_container
* class --hence, this allocator needs also be stored resorting
* to the base from member trick.
*/
template<typename NodeType,typename Final>
struct header_holder:base_from_member<NodeType*>,private noncopyable
template<typename NodeTypePtr,typename Final>
struct header_holder:private noncopyable
{
header_holder():super(final().allocate_node()){}
~header_holder(){final().deallocate_node(super::member);}
header_holder():member(final().allocate_node()){}
~header_holder(){final().deallocate_node(&*member);}
NodeTypePtr member;
private:
typedef base_from_member<NodeType*> super;
Final& final(){return *static_cast<Final*>(this);}
};
@@ -0,0 +1,18 @@
/* Copyright 2003-2016 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#include <boost/config.hpp>
#if defined(BOOST_GCC)&&(BOOST_GCC>=4*10000+6*100)
#if !defined(BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#else
#pragma GCC diagnostic pop
#endif
#endif
@@ -0,0 +1,77 @@
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_ACCESS_SEQUENCE_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_ACCESS_SEQUENCE_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mp11/list.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/multi_index_container_fwd.hpp>
namespace boost{
namespace multi_index{
namespace detail{
/* Successive access to the indices of a multi_index_container. Used as dst in
* backbone function extract_(x,dst) to retrieve the destination indices
* where iterators referring to x must be transferred to (in merging
* operations).
*/
template<typename MultiIndexContainer,int N=0>
struct index_access_sequence;
struct index_access_sequence_terminal
{
index_access_sequence_terminal(void*){}
};
template<typename MultiIndexContainer,int N>
struct index_access_sequence_normal
{
MultiIndexContainer* p;
index_access_sequence_normal(MultiIndexContainer* p_):p(p_){}
typename nth_index<MultiIndexContainer,N>::type&
get(){return p->template get<N>();}
index_access_sequence<MultiIndexContainer,N+1>
next(){return index_access_sequence<MultiIndexContainer,N+1>(p);}
};
template<typename MultiIndexContainer,int N>
using index_access_sequence_base=mp11::mp_if_c<
N<mp11::mp_size<typename MultiIndexContainer::index_type_list>::value,
index_access_sequence_normal<MultiIndexContainer,N>,
index_access_sequence_terminal
>;
template<typename MultiIndexContainer,int N>
struct index_access_sequence:index_access_sequence_base<MultiIndexContainer,N>
{
typedef index_access_sequence_base<
MultiIndexContainer,N> super;
index_access_sequence(MultiIndexContainer* p):super(p){}
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
+184 -36
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2026 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,16 +9,20 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/call_traits.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/multi_index/detail/copy_map.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/index_access_sequence.hpp>
#include <boost/multi_index/detail/node_handle.hpp>
#include <boost/multi_index/detail/node_type.hpp>
#include <boost/multi_index/detail/type_list.hpp>
#include <boost/multi_index_container_fwd.hpp>
#include <boost/tuple/tuple.hpp>
#include <utility>
@@ -42,80 +46,152 @@ namespace detail{
* cannot be called directly from the index classes.)
*/
struct lvalue_tag{};
struct rvalue_tag{};
struct emplaced_tag{};
template<typename Value,typename IndexSpecifierList,typename Allocator>
class index_base
{
protected:
typedef index_node_base<Value> node_type;
typedef index_node_base<Value,Allocator> index_node_type;
typedef typename multi_index_node_type<
Value,IndexSpecifierList,Allocator>::type final_node_type;
typedef multi_index_container<
Value,IndexSpecifierList,Allocator> final_type;
typedef tuples::null_type ctor_args_list;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
typename Allocator::value_type>::type final_allocator_type;
typedef mpl::vector0<> index_type_list;
typedef mpl::vector0<> iterator_type_list;
typedef mpl::vector0<> const_iterator_type_list;
typedef Allocator final_allocator_type;
typedef node_handle<
final_node_type,final_allocator_type> final_node_handle_type;
typedef empty_type_list index_type_list;
typedef empty_type_list iterator_type_list;
typedef empty_type_list const_iterator_type_list;
typedef copy_map<
final_node_type,
final_allocator_type> copy_map_type;
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
typedef index_saver<
node_type,
index_node_type,
final_allocator_type> index_saver_type;
typedef index_loader<
node_type,
index_node_type,
final_node_type,
final_allocator_type> index_loader_type;
#endif
private:
typedef typename call_traits<Value>::param_type value_param_type;
typedef Value value_type;
typedef allocator_size_type_t<Allocator> size_type;
protected:
explicit index_base(const ctor_args_list&,const Allocator&){}
explicit index_base(
const ctor_args_list&,const Allocator&,index_node_type*){}
index_base(
const index_base<Value,IndexSpecifierList,Allocator>&,
const Allocator&,index_node_type*){}
index_base(
const index_base<Value,IndexSpecifierList,Allocator>&,
const Allocator&,index_node_type*,
do_not_copy_elements_tag)
{}
void copy_(
const index_base<Value,IndexSpecifierList,Allocator>&,const copy_map_type&)
{}
node_type* insert_(value_param_type v,node_type* x)
final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag)
{
boost::detail::allocator::construct(&x->value,v);
x=final().allocate_node();
BOOST_TRY{
final().construct_value(x,v);
}
BOOST_CATCH(...){
final().deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
return x;
}
node_type* insert_(value_param_type v,node_type*,node_type* x)
final_node_type* insert_(const value_type& v,final_node_type*& x,rvalue_tag)
{
boost::detail::allocator::construct(&x->value,v);
x=final().allocate_node();
BOOST_TRY{
final().construct_value(x,std::move(const_cast<value_type&>(v)));
}
BOOST_CATCH(...){
final().deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
return x;
}
void erase_(node_type* x)
final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag)
{
boost::detail::allocator::destroy(&x->value);
return x;
}
void delete_node_(node_type* x)
template<typename MultiIndexContainer>
final_node_type* insert_(
const value_type&,final_node_type*& x,MultiIndexContainer* p)
{
boost::detail::allocator::destroy(&x->value);
p->final_extract_for_transfer_(
x,index_access_sequence<final_type>(&final()));
return x;
}
final_node_type* insert_(
const value_type& v,index_node_type*,final_node_type*& x,lvalue_tag)
{
return insert_(v,x,lvalue_tag());
}
final_node_type* insert_(
const value_type& v,index_node_type*,final_node_type*& x,rvalue_tag)
{
return insert_(v,x,rvalue_tag());
}
final_node_type* insert_(
const value_type&,index_node_type*,final_node_type*& x,emplaced_tag)
{
return x;
}
template<typename Dst>
void extract_(index_node_type*,Dst){}
void clear_(){}
void swap_(index_base<Value,IndexSpecifierList,Allocator>&){}
template<typename BoolConstant>
void swap_(
index_base<Value,IndexSpecifierList,Allocator>&,
BoolConstant /* swap_allocators */)
{}
bool replace_(value_param_type v,node_type* x)
void swap_elements_(index_base<Value,IndexSpecifierList,Allocator>&){}
bool replace_(const value_type& v,index_node_type* x,lvalue_tag)
{
x->value=v;
x->value()=v;
return true;
}
bool modify_(node_type*){return true;}
bool replace_(const value_type& v,index_node_type* x,rvalue_tag)
{
x->value()=std::move(const_cast<value_type&>(v));
return true;
}
bool modify_(index_node_type*){return true;}
bool modify_rollback_(index_node_type*){return true;}
bool check_rollback_(index_node_type*)const{return true;}
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
/* serialization */
@@ -138,17 +214,74 @@ protected:
final_type& final(){return *static_cast<final_type*>(this);}
const final_type& final()const{return *static_cast<const final_type*>(this);}
template<typename Index>
static typename Index::final_type& final(Index& x) /* cross-index access */
{return static_cast<typename Index::final_type&>(x);}
final_node_type* final_header()const{return final().header();}
bool final_empty_()const{return final().empty_();}
std::size_t final_size_()const{return final().size_();}
std::size_t final_max_size_()const{return final().max_size_();}
bool final_empty_()const{return final().empty_();}
size_type final_size_()const{return final().size_();}
size_type final_max_size_()const{return final().max_size_();}
std::pair<final_node_type*,bool> final_insert_(value_param_type x)
std::pair<final_node_type*,bool> final_insert_(const value_type& x)
{return final().insert_(x);}
std::pair<final_node_type*,bool> final_insert_rv_(const value_type& x)
{return final().insert_rv_(x);}
template<typename T>
std::pair<final_node_type*,bool> final_insert_ref_(const T& t)
{return final().insert_ref_(t);}
template<typename T>
std::pair<final_node_type*,bool> final_insert_ref_(T& t)
{return final().insert_ref_(t);}
std::pair<final_node_type*,bool> final_insert_nh_(final_node_handle_type& nh)
{return final().insert_nh_(nh);}
template<typename Index>
std::pair<final_node_type*,bool> final_transfer_(Index& x,final_node_type* n)
{return final().transfer_(x,n);}
template<typename... Args>
std::pair<final_node_type*,bool> final_emplace_(Args&&... args)
{
return final().emplace_(std::forward<Args>(args)...);
}
std::pair<final_node_type*,bool> final_insert_(
value_param_type x,final_node_type* position)
const value_type& x,final_node_type* position)
{return final().insert_(x,position);}
std::pair<final_node_type*,bool> final_insert_rv_(
const value_type& x,final_node_type* position)
{return final().insert_rv_(x,position);}
template<typename T>
std::pair<final_node_type*,bool> final_insert_ref_(
const T& t,final_node_type* position)
{return final().insert_ref_(t,position);}
template<typename T>
std::pair<final_node_type*,bool> final_insert_ref_(
T& t,final_node_type* position)
{return final().insert_ref_(t,position);}
std::pair<final_node_type*,bool> final_insert_nh_(
final_node_handle_type& nh,final_node_type* position)
{return final().insert_nh_(nh,position);}
template<typename... Args>
std::pair<final_node_type*,bool> final_emplace_hint_(
final_node_type* position,Args&&... args)
{
return final().emplace_hint_(position,std::forward<Args>(args)...);
}
final_node_handle_type final_extract_(final_node_type* x)
{
return final().extract_(x);
}
template<typename Dst>
void final_extract_for_transfer_(final_node_type* x,Dst dst)
{
final().extract_for_transfer_(x,dst);
}
void final_erase_(final_node_type* x){final().erase_(x);}
@@ -156,15 +289,30 @@ protected:
void final_delete_all_nodes_(){final().delete_all_nodes_();}
void final_clear_(){final().clear_();}
template<typename Index>
void final_transfer_range_(
Index& x,
typename Index::iterator first,
typename Index::iterator last)
{final().transfer_range_(x,first,last);}
void final_swap_(final_type& x){final().swap_(x);}
bool final_replace_(
value_param_type k,final_node_type* x)
const value_type& k,final_node_type* x)
{return final().replace_(k,x);}
bool final_replace_rv_(
const value_type& k,final_node_type* x)
{return final().replace_rv_(k,x);}
template<typename Modifier>
bool final_modify_(Modifier mod,final_node_type* x)
bool final_modify_(Modifier& mod,final_node_type* x)
{return final().modify_(mod,x);}
template<typename Modifier,typename Rollback>
bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x)
{return final().modify_(mod,back,x);}
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
void final_check_invariant_()const{final().check_invariant_();}
#endif
@@ -1,180 +0,0 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_ITERATOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_ITERATOR_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#include <boost/multi_index/detail/index_iterator_fwd.hpp>
#include <boost/multi_index/detail/index_proxy.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/operators.hpp>
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/split_member.hpp>
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* An iterator template for nodes of multi_index::detail::index.
* Built with the aid boost::bidirectional_iterator_helper from
* boost/operators.hpp.
*/
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
template<typename Node>
class index_iterator:
public boost::bidirectional_iterator_helper<
index_iterator<Node>,
typename Node::value_type,
std::ptrdiff_t,
const typename Node::value_type*,
const typename Node::value_type&>,
public safe_iterator<index_proxy<Node> >
#else
template<typename Node,typename Container>
class index_iterator:
public boost::bidirectional_iterator_helper<
index_iterator<Node,Container>,
typename Node::value_type,
std::ptrdiff_t,
const typename Node::value_type*,
const typename Node::value_type&>,
public safe_iterator<Container>
#endif
#else
template<typename Node>
class index_iterator:
public boost::bidirectional_iterator_helper<
index_iterator<Node>,
typename Node::value_type,
std::ptrdiff_t,
const typename Node::value_type*,
const typename Node::value_type&>
#endif
{
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
public:
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
typedef index_proxy<Node> container_type;
#else
typedef Container container_type;
#endif
private:
typedef safe_iterator<container_type> safe_super;
public:
index_iterator():node(0){}
index_iterator(Node* node_,container_type* cont_):
safe_super(cont_),node(node_){}
index_iterator& operator=(const index_iterator& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x);
safe_super::operator=(x);
node=x.node;
return *this;
}
#else
public:
index_iterator(){}
index_iterator(Node* node_):node(node_){}
#endif
const typename Node::value_type& operator*()const
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this);
return node->value;
}
index_iterator& operator++()
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this);
Node::increment(node);
return *this;
}
index_iterator& operator--()
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(*this);
Node::decrement(node);
return *this;
}
friend bool operator==(const index_iterator& x,const index_iterator& y)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x);
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(y);
BOOST_MULTI_INDEX_CHECK_SAME_OWNER(x,y);
return x.node==y.node;
}
/* get_node is not to be used by the user */
Node* get_node()const{return node;}
private:
Node* node;
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
/* serialization */
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
typedef typename Node::base_type node_base_type;
template<class Archive>
void save(Archive& ar,const unsigned int version)const
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
node_base_type* bnode=node;
ar<<serialization::make_nvp("pointer",bnode);
}
template<class Archive>
void load(Archive& ar,const unsigned int version)
{
node_base_type* bnode;
ar>>serialization::make_nvp("pointer",bnode);
node=static_cast<Node*>(bnode);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::uncheck();
#endif
}
#endif
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,44 +0,0 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_ITERATOR_FWD_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_ITERATOR_FWD_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
namespace boost{
namespace multi_index{
namespace detail{
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
template<typename Node>
class index_iterator;
#else
template<typename Node,typename Container>
class index_iterator;
#endif
#else
template<typename Node>
class index_iterator;
#endif
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,16 +9,17 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/archive/archive_exception.hpp>
#include <boost/noncopyable.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/core/serialization.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/multi_index/detail/bad_archive_exception.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <boost/throw_exception.hpp>
#include <cstddef>
@@ -29,7 +30,8 @@ namespace multi_index{
namespace detail{
/* Counterpart of index_saver (check index_saver.hpp for serialization
* details.)* multi_index_container is in charge of supplying the info about
* details.)
* multi_index_container is in charge of supplying the info about
* the base sequence, and each index can subsequently load itself using the
* const interface of index_loader.
*/
@@ -46,14 +48,14 @@ public:
template<class Archive>
void add(Node* node,Archive& ar,const unsigned int)
{
ar>>serialization::make_nvp("position",*node);
ar>>core::make_nvp("position",*node);
entries()[n++]=node;
}
template<class Archive>
void add_track(Node* node,Archive& ar,const unsigned int)
{
ar>>serialization::make_nvp("position",*node);
ar>>core::make_nvp("position",*node);
}
/* A rearranger is passed two nodes, and is expected to
@@ -91,7 +93,7 @@ public:
}
private:
Node** entries()const{return spc.data();}
Node** entries()const{return raw_ptr<Node**>(spc.data());}
/* We try to delay sorting as much as possible just in case it
* is not necessary, hence this version of load_node.
@@ -101,7 +103,7 @@ private:
FinalNode* unchecked_load_node(Archive& ar)const
{
Node* node=0;
ar>>serialization::make_nvp("pointer",node);
ar>>core::make_nvp("pointer",node);
return static_cast<FinalNode*>(node);
}
@@ -109,7 +111,7 @@ private:
FinalNode* load_node(Archive& ar)const
{
Node* node=0;
ar>>serialization::make_nvp("pointer",node);
ar>>core::make_nvp("pointer",node);
check_node(node);
return static_cast<FinalNode*>(node);
}
@@ -117,9 +119,7 @@ private:
void check_node(Node* node)const
{
if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){
throw_exception(
archive::archive_exception(
archive::archive_exception::other_exception));
throw_exception(bad_archive_exception());
}
}
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,14 +9,15 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <cstddef>
#include <functional>
@@ -106,14 +107,14 @@ class algorithm_base:private noncopyable
{
protected:
algorithm_base(const Allocator& al,std::size_t size):
spc(al,size),size_(size),n(0),sorted(false)
spc(al,size),size_(size),n_(0),sorted(false)
{
}
void add(void* node)
{
entries()[n]=entry(node,n);
++n;
entries()[n_]=entry(node,n_);
++n_;
}
void begin_algorithm()const
@@ -179,11 +180,11 @@ protected:
}
private:
entry* entries()const{return spc.data();}
entry* entries()const{return raw_ptr<entry*>(spc.data());}
auto_space<entry,Allocator> spc;
std::size_t size_;
std::size_t n;
std::size_t n_;
mutable bool sorted;
mutable std::size_t num_piles;
};
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,14 +9,17 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/archive/archive_exception.hpp>
#include <boost/serialization/access.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/core/serialization.hpp>
#include <boost/multi_index/detail/bad_archive_exception.hpp>
#include <boost/throw_exception.hpp>
#endif
@@ -31,16 +34,43 @@ namespace detail{
*/
template<typename Value>
struct index_node_base
struct pod_value_holder
{
typename aligned_storage<
sizeof(Value),
alignment_of<Value>::value
>::type space;
};
template<typename Value,typename Allocator>
struct index_node_base:private pod_value_holder<Value>
{
typedef index_node_base base_type; /* used for serialization purposes */
typedef Value value_type;
value_type value;
typedef Allocator allocator_type;
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
value_type& value()
{
return *reinterpret_cast<value_type*>(&this->space);
}
const value_type& value()const
{
return *reinterpret_cast<const value_type*>(&this->space);
}
#include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
static index_node_base* from_value(const value_type* p)
{
return static_cast<index_node_base *>(
reinterpret_cast<pod_value_holder<Value>*>( /* std 9.2.17 */
const_cast<value_type*>(p)));
}
private:
index_node_base();
/* this class is not intended to be cted, merely allocated */
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
friend class boost::serialization::access;
@@ -54,9 +84,16 @@ private:
{
}
#endif
};
template<typename Node,typename Value>
Node* node_from_value(const Value* p)
{
typedef typename Node::allocator_type allocator_type;
return static_cast<Node*>(
index_node_base<Value,allocator_type>::from_value(p));
}
} /* namespace multi_index::detail */
} /* namespace multi_index */
@@ -68,28 +105,19 @@ private:
* somehow invalid archive.
*/
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
namespace serialization{
#else
namespace multi_index{
namespace detail{
#endif
template<class Archive,typename Value>
template<class Archive,typename Value,typename Allocator>
inline void load_construct_data(
Archive&,boost::multi_index::detail::index_node_base<Value>*,
Archive&,boost::multi_index::detail::index_node_base<Value,Allocator>*,
const unsigned int)
{
throw_exception(
archive::archive_exception(archive::archive_exception::other_exception));
throw_exception(boost::multi_index::detail::bad_archive_exception());
}
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
} /* namespace serialization */
#else
} /* namespace multi_index::detail */
} /* namespace multi_index */
#endif
#endif
@@ -1,82 +0,0 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_PROXY_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_PROXY_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
#include <algorithm>
#include <boost/multi_index/detail/index_iterator_fwd.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
namespace boost{
namespace multi_index{
namespace detail{
/* In safe mode, index iterators are derived from safe_iterator<Index>,
* where Index is the type of the index where the iterator belongs. Due
* to the long symbol names of indices, MSVC++ 6.0 often issues a
* LNK1179 (duplicate comdat) error. To workaround this problem,
* index_proxy is used instead. index_proxy<Node> acts as an index
* over nodes of type Node in all aspects relevant to safe_iterator, and
* its shorter symbol name makes life easier for MSVC++ 6.0.
*/
template<typename Node>
class index_proxy:public safe_container<index_proxy<Node> >
{
protected:
index_proxy(Node* header_):header(header_){}
void swap(index_proxy<Node>& x)
{
std::swap(header,x.header);
safe_container<index_proxy<Node> >::swap(x);
}
public:
typedef index_iterator<Node> iterator;
typedef index_iterator<Node> const_iterator;
index_iterator<Node> begin()const
{
return index_iterator<Node>(
Node::begin(header),const_cast<index_proxy*>(this));
}
index_iterator<Node> end()const
{
return index_iterator<Node>(
Node::end(header),const_cast<index_proxy*>(this));
}
private:
Node* header;
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif /* workaround */
#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,14 +9,14 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/multi_index/detail/index_matcher.hpp>
#include <boost/noncopyable.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/core/serialization.hpp>
#include <cstddef>
namespace boost{
@@ -43,14 +43,14 @@ public:
template<class Archive>
void add(Node* node,Archive& ar,const unsigned int)
{
ar<<serialization::make_nvp("position",*node);
ar<<core::make_nvp("position",*node);
alg.add(node);
}
template<class Archive>
void add_track(Node* node,Archive& ar,const unsigned int)
{
ar<<serialization::make_nvp("position",*node);
ar<<core::make_nvp("position",*node);
}
template<typename IndexIterator,class Archive>
@@ -120,7 +120,7 @@ private:
template<typename Archive>
static void save_node(Node* node,Archive& ar)
{
ar<<serialization::make_nvp("pointer",node);
ar<<core::make_nvp("pointer",node);
}
index_matcher::algorithm<Node,Allocator> alg;
@@ -0,0 +1,44 @@
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_INVALIDATE_ITERATORS_HPP
#define BOOST_MULTI_INDEX_DETAIL_INVALIDATE_ITERATORS_HPP
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* invalidate_iterators mimics the interface of index_access_sequence (see
* index_access_sequence.hpp) but returns dummy indices whose iterator type
* won't ever match those of the source: the net effect is that safe iterator
* transfer resolves to iterator invalidation, so backbone function invocation
* extract_(x,invalidate_iterators()) is used in extraction scenarios other
* than merging.
*/
struct invalidate_iterators
{
typedef void iterator;
invalidate_iterators& get(){return *this;}
invalidate_iterators& next(){return *this;}
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP
#define BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
@@ -0,0 +1,51 @@
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_FUNCTION_HPP
#define BOOST_MULTI_INDEX_DETAIL_IS_FUNCTION_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(_LIBCPP_VERSION,<30700)||\
BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40802)
/* libc++: std::is_function<void() const> fails,
* https://bugs.llvm.org/show_bug.cgi?id=20084
*
* libstdc++-v3: std::is_function does not support ref-qualified function types,
* https://github.com/gcc-mirror/gcc/commit/
* 2fa630fb50ba29d8e891c52a75aaec261b07874e#
* diff-6547f965a8d66bf35a6388fcf404aaa3
*/
#include <boost/type_traits/is_function.hpp>
namespace boost{namespace multi_index{namespace detail{
template<typename T>
struct is_function:boost::is_function<T>{};
}}} /* namespace boost::multi_index::detail */
#else
#include <type_traits>
namespace boost{namespace multi_index{namespace detail{
template<typename T>
struct is_function:std::is_function<T>{};
}}} /* namespace boost::multi_index::detail */
#endif
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,13 +9,51 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP
#define BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/empty.hpp>
#include <boost/mpl/is_sequence.hpp>
#if defined(BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT)
#include <boost/multi_index/detail/mpl_to_mp11_list.hpp>
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
<boost/mpl/empty.hpp>
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
<boost/mpl/is_sequence.hpp>
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#include <type_traits>
namespace boost{
namespace multi_index{
namespace detail{
/* an index list is a non-empty MPL sequence */
template<typename T>
struct is_index_list
{
BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence<T>::value);
BOOST_STATIC_CONSTANT(bool,non_empty=!(std::conditional<
mpl_sequence,mpl::empty<T>,std::false_type>::type::value));
BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty);
};
template<typename IndexList>
using mp11_index_list=mpl_to_mp11_list<IndexList>;
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#else
#include <type_traits>
namespace boost{
@@ -24,17 +62,19 @@ namespace multi_index{
namespace detail{
template<typename T>
struct is_index_list
{
BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence<T>::value);
BOOST_STATIC_CONSTANT(bool,non_empty=!mpl::empty<T>::value);
BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty);
};
struct is_index_list:std::false_type{};
/* an index list is a non-empty Mp11 list */
template<template<typename...> class L,typename T,typename... Ts>
struct is_index_list<L<T,Ts...>>:std::true_type{};
template<typename IndexList>
using mp11_index_list=IndexList;
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
#endif
@@ -0,0 +1,124 @@
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP
#define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/type_traits/intrinsics.hpp>
#include <type_traits>
namespace boost{
namespace multi_index{
namespace detail{
/* Metafunction that checks if f(arg,arg2) executes without argument type
* conversion. By default (i.e. when it cannot be determined) it evaluates to
* true.
*/
template<typename F,typename Arg1,typename Arg2,typename=void>
struct is_transparent:std::true_type{};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#if !defined(BOOST_NO_SFINAE_EXPR)&& \
(defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL))
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_final.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_pointer.hpp>
namespace boost{
namespace multi_index{
namespace detail{
struct not_is_transparent_result_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent_class_helper:F
{
using F::operator();
template<typename T,typename Q>
not_is_transparent_result_type operator()(const T&,const Q&)const;
};
template<typename F,typename Arg1,typename Arg2,typename=void>
struct is_transparent_class:std::true_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent_class<
F,Arg1,Arg2,
typename enable_if<
is_same<
decltype(
declval<const is_transparent_class_helper<F,Arg1,Arg2> >()(
declval<const Arg1&>(),declval<const Arg2&>())
),
not_is_transparent_result_type
>
>::type
>:std::false_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent<
F,Arg1,Arg2,
typename enable_if_c<
is_class<F>::value&&
!is_final<F>::value /* is_transparent_class_helper derives from F */
>::type
>:is_transparent_class<F,Arg1,Arg2>{};
template<typename F,typename Arg1,typename Arg2,typename=void>
struct is_transparent_function:std::true_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent_function<
F,Arg1,Arg2,
typename enable_if_c<
!(is_same<typename function_traits<F>::arg1_type,const Arg1&>::value||
is_same<typename function_traits<F>::arg1_type,Arg1>::value)
||
!(is_same<typename function_traits<F>::arg2_type,const Arg2&>::value||
is_same<typename function_traits<F>::arg2_type,Arg2>::value)
>::type
>:std::false_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent<
F,Arg1,Arg2,
typename enable_if<
is_function<typename remove_pointer<F>::type>
>::type
>:is_transparent_function<typename remove_pointer<F>::type,Arg1,Arg2>{};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
#endif
@@ -0,0 +1,309 @@
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mp11/utility.hpp>
#include <boost/operators.hpp>
namespace boost{
namespace multi_index{
namespace detail{
/* Poor man's version of boost::iterator_adaptor. Used instead of the
* original as compile times for the latter are significantly higher.
* The interface is not replicated exactly, only to the extent necessary
* for internal consumption.
*/
/* NB. The purpose of the (non-inclass) global operators ==, < and - defined
* above is to partially alleviate a problem of MSVC++ 6.0 by * which
* friend-injected operators on T are not visible if T is instantiated only
* in template code where T is a dependent type.
*/
class iter_adaptor_access
{
public:
template<class Class>
static typename Class::reference dereference(const Class& x)
{
return x.dereference();
}
template<class Class>
static bool equal(const Class& x,const Class& y)
{
return x.equal(y);
}
template<class Class>
static void increment(Class& x)
{
x.increment();
}
template<class Class>
static void decrement(Class& x)
{
x.decrement();
}
template<class Class>
static void advance(Class& x,typename Class::difference_type n)
{
x.advance(n);
}
template<class Class>
static typename Class::difference_type distance_to(
const Class& x,const Class& y)
{
return x.distance_to(y);
}
};
template<typename Category>
struct iter_adaptor_selector;
template<class Derived,class Base>
class forward_iter_adaptor_base:
public forward_iterator_helper<
Derived,
typename Base::value_type,
typename Base::difference_type,
typename Base::pointer,
typename Base::reference>
{
public:
typedef typename Base::reference reference;
reference operator*()const
{
return iter_adaptor_access::dereference(final());
}
friend bool operator==(const Derived& x,const Derived& y)
{
return iter_adaptor_access::equal(x,y);
}
Derived& operator++()
{
iter_adaptor_access::increment(final());
return final();
}
private:
Derived& final(){return *static_cast<Derived*>(this);}
const Derived& final()const{return *static_cast<const Derived*>(this);}
};
template<class Derived,class Base>
bool operator==(
const forward_iter_adaptor_base<Derived,Base>& x,
const forward_iter_adaptor_base<Derived,Base>& y)
{
return iter_adaptor_access::equal(
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
}
template<>
struct iter_adaptor_selector<std::forward_iterator_tag>
{
template<class Derived,class Base>
using fn=forward_iter_adaptor_base<Derived,Base>;
};
template<class Derived,class Base>
class bidirectional_iter_adaptor_base:
public bidirectional_iterator_helper<
Derived,
typename Base::value_type,
typename Base::difference_type,
typename Base::pointer,
typename Base::reference>
{
public:
typedef typename Base::reference reference;
reference operator*()const
{
return iter_adaptor_access::dereference(final());
}
friend bool operator==(const Derived& x,const Derived& y)
{
return iter_adaptor_access::equal(x,y);
}
Derived& operator++()
{
iter_adaptor_access::increment(final());
return final();
}
Derived& operator--()
{
iter_adaptor_access::decrement(final());
return final();
}
private:
Derived& final(){return *static_cast<Derived*>(this);}
const Derived& final()const{return *static_cast<const Derived*>(this);}
};
template<class Derived,class Base>
bool operator==(
const bidirectional_iter_adaptor_base<Derived,Base>& x,
const bidirectional_iter_adaptor_base<Derived,Base>& y)
{
return iter_adaptor_access::equal(
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
}
template<>
struct iter_adaptor_selector<std::bidirectional_iterator_tag>
{
template<class Derived,class Base>
using fn=bidirectional_iter_adaptor_base<Derived,Base>;
};
template<class Derived,class Base>
class random_access_iter_adaptor_base:
public random_access_iterator_helper<
Derived,
typename Base::value_type,
typename Base::difference_type,
typename Base::pointer,
typename Base::reference>
{
public:
typedef typename Base::reference reference;
typedef typename Base::difference_type difference_type;
reference operator*()const
{
return iter_adaptor_access::dereference(final());
}
friend bool operator==(const Derived& x,const Derived& y)
{
return iter_adaptor_access::equal(x,y);
}
friend bool operator<(const Derived& x,const Derived& y)
{
return iter_adaptor_access::distance_to(x,y)>0;
}
Derived& operator++()
{
iter_adaptor_access::increment(final());
return final();
}
Derived& operator--()
{
iter_adaptor_access::decrement(final());
return final();
}
Derived& operator+=(difference_type n)
{
iter_adaptor_access::advance(final(),n);
return final();
}
Derived& operator-=(difference_type n)
{
iter_adaptor_access::advance(final(),-n);
return final();
}
friend difference_type operator-(const Derived& x,const Derived& y)
{
return iter_adaptor_access::distance_to(y,x);
}
private:
Derived& final(){return *static_cast<Derived*>(this);}
const Derived& final()const{return *static_cast<const Derived*>(this);}
};
template<class Derived,class Base>
bool operator==(
const random_access_iter_adaptor_base<Derived,Base>& x,
const random_access_iter_adaptor_base<Derived,Base>& y)
{
return iter_adaptor_access::equal(
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
}
template<class Derived,class Base>
bool operator<(
const random_access_iter_adaptor_base<Derived,Base>& x,
const random_access_iter_adaptor_base<Derived,Base>& y)
{
return iter_adaptor_access::distance_to(
static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0;
}
template<class Derived,class Base>
typename random_access_iter_adaptor_base<Derived,Base>::difference_type
operator-(
const random_access_iter_adaptor_base<Derived,Base>& x,
const random_access_iter_adaptor_base<Derived,Base>& y)
{
return iter_adaptor_access::distance_to(
static_cast<const Derived&>(y),static_cast<const Derived&>(x));
}
template<>
struct iter_adaptor_selector<std::random_access_iterator_tag>
{
template<class Derived,class Base>
using fn=random_access_iter_adaptor_base<Derived,Base>;
};
template<class Derived,class Base>
using iter_adaptor_base=mp11::mp_invoke_q<
iter_adaptor_selector<typename Base::iterator_category>,
Derived,Base
>;
template<class Derived,class Base>
class iter_adaptor:public iter_adaptor_base<Derived,Base>
{
protected:
iter_adaptor(){}
explicit iter_adaptor(const Base& b_):b(b_){}
const Base& base_reference()const{return b;}
Base& base_reference(){return b;}
private:
Base b;
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaquín M López Muñoz.
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#if defined(_MSC_VER)
#pragma once
#endif
@@ -24,19 +24,19 @@ namespace detail{
* with references to references, dealing with function pointers, etc.
*/
template<typename Modifier,typename Value,typename KeyFromValue>
template<typename Fun,typename Value,typename KeyFromValue>
struct modify_key_adaptor
{
modify_key_adaptor(Modifier mod_,KeyFromValue kfv_):mod(mod_),kfv(kfv_){}
modify_key_adaptor(Fun f_,KeyFromValue kfv_):f(f_),kfv(kfv_){}
void operator()(Value& x)
{
mod(kfv(x));
f(kfv(x));
}
private:
Modifier mod;
Fun f;
KeyFromValue kfv;
};
@@ -0,0 +1,62 @@
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_MPL_TO_MP11_LIST_HPP
#define BOOST_MULTI_INDEX_DETAIL_MPL_TO_MP11_LIST_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#if defined(BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT)
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mp11/list.hpp>
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
<boost/mpl/begin_end.hpp>
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
<boost/mpl/deref.hpp>
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
<boost/mpl/next.hpp>
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
namespace boost{
namespace multi_index{
namespace detail{
template<typename First,typename Last,typename... Ts>
struct mpl_to_mp11_list_impl:mpl_to_mp11_list_impl<
typename mpl::next<First>::type,Last,
Ts...,typename mpl::deref<First>::type
>{};
template<typename Last,typename... Ts>
struct mpl_to_mp11_list_impl<Last,Last,Ts...>
{
using type=mp11::mp_list<Ts...>;
};
template<typename TypeList>
using mpl_to_mp11_list=typename mpl_to_mp11_list_impl<
typename mpl::begin<TypeList>::type,
typename boost::mpl::end<TypeList>::type
>::type;
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More