Compare commits

...

206 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
162 changed files with 11135 additions and 5221 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()
+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
;
-390
View File
@@ -1,390 +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">
<link rel="start" href="index.html">
<link rel="prev" href="reference/key_extraction.html">
<link rel="up" href="index.html">
<link rel="next" href="performance.html">
</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 utilizes some C++11 capabilities but is also equipped
to work reasonably well in decent C++03-compliant environments.
We list some of the possible limitations along with suitable workarounds when available.
</p>
<h2>Contents</h2>
<ul>
<li><a href="#move">Move semantics</a></li>
<li><a href="#emplace">Emplace functions</a></li>
<li><a href="#initializer_list">Initializer lists</a></li>
<li><a href="#tuple">Tuples</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>
<li><a href="#legacy">Legacy compilers</a></li>
</ul>
<h2><a name="move">Move semantics</a></h2>
<p>
Boost.MultiIndex uses <a href="../../../doc/html/move.html">Boost.Move</a>
to support compilers without rvalue references. In such scenarios, taking
advantage of <code>multi_index_container&lt;Value&gt;</code> capabilities for
increased efficiency in insertion and handling of moveable-only elements will
require that <code>Value</code> be suitably instrumented.
</p>
<h2><a name="emplace">Emplace functions</a></h2>
<p>
In compilers without variadic template support, Boost.MultiIndex emplace
functions emulate this missing functionality by accepting up to
<code>BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS</code>
construction arguments that are internally forwarded with
<a href="../../../doc/html/move.html">Boost.Move</a>:
only constant lvalue references and rvalues are permitted as construction arguments
in such case.
</p>
<p>
<code>BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS</code>, which by default is 5, can
be globally defined by the user to a different value.
</p>
<h2><a name="initializer_list">Initializer lists</a></h2>
<p>
No transparent emulation of this functionality can be provided in the absence of
<code>std::initializer_list</code>: consider
<a href="../../../libs/assign/index.html">Boost.Assign</a> as a
possible replacement.
</p>
<h2><a name="tuple">Tuples</a></h2>
<p>
Everywhere where <code>std::tuple</code>s are used in the library interface,
<code>boost::tuple</code>s can be resorted to in their place. The converse, however,
is not true.
</p>
<h2><a name="symbol_reduction">Reduction of symbol name lengths</a></h2>
<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>
<h3><a name="argument_limitation">Limitation of maximum number of arguments</a></h3>
<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>
</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>
</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>
</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>
</tr>
</table>
</p>
<h3><a name="type_hiding">Type hiding</a></h3>
<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_index&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 specifier 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_index&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>
<h2><a name="legacy">Legacy compilers</a></h2>
<p>
Boost.MultiIndex support for legacy compilers is not actively kept, so if you happen
to work with an old environment you might need to use a former version of the library.
A table is provided of some legacy compilers along with the latest version of
Boost.MultiIndex known to work for them (frequently with limitations as explained
in the corresponding compiler specifics section.) If you successfully try one of those
with newer versions of Boost.MultiIndex than stated here, please report back so that
the information can be updated.
</p>
<p align="center">
<table cellspacing="0" cellpadding="5">
<caption><b>Support for legacy compilers.</b></caption>
<tr>
<th>Compiler</th>
<th>Latest known<br>compatible version</th>
<th>Date</th>
</tr>
<tr>
<td>Borland C++ Builder 6.4 through 2006, CodeGear C++Builder 2010</td>
<td>Never worked with Boost.MultiIndex</td>
<td></td>
</tr>
<tr class="odd_tr">
<td>Comeau C/C++ 4.3.10.1 for Windows (VC++ 9.0 backend)</td>
<td><a href="http://www.boost.org/doc/libs/1_38_0/libs/multi_index/doc/compiler_specifics.html#comeau_43101_win_vc7_71">Boost 1.38</a></td>
<td>February 2009</td>
</tr>
<tr>
<td>Compaq C++ 6.5-042 through 7.1-006 for Tru64 UNIX</td>
<td><a href="http://www.boost.org/doc/libs/1_38_0/libs/multi_index/doc/compiler_specifics.html#compaq_65">Boost 1.38</a></td>
<td>February 2009</td>
</tr>
<tr class="odd_tr">
<td>GCC 3.2 through 3.4</td>
<td><a href="http://www.boost.org/doc/libs/1_41_0/libs/multi_index/doc/compiler_specifics.html#gcc_32">Boost 1.41</a></td>
<td>November 2009</td>
</tr>
<tr>
<td>HP aC++ A.06.12 through A.06.17 for HP-UX IA64</td>
<td><a href="http://www.boost.org/doc/libs/1_38_0/libs/multi_index/doc/compiler_specifics.html#acc_612_ia64">Boost 1.38</a></td>
<td>February 2009</td>
</tr>
<tr class="odd_tr">
<td>HP aC++ A.03.80 through A.03.85 for HP-UX PA-RISC</td>
<td><a href="http://www.boost.org/doc/libs/1_38_0/libs/multi_index/doc/compiler_specifics.html#acc_380_pa_risc">Boost 1.38</a></td>
<td>February 2009</td>
</tr>
<tr>
<td>IBM VisualAge C++ V6.0 for AIX</td>
<td><a href="http://www.boost.org/doc/libs/1_33_1/libs/multi_index/doc/compiler_specifics.html#va_60">Boost 1.33.1</a></td>
<td>December 2006</td>
</tr>
<tr class="odd_tr">
<td>IBM XL C/C++ V9.0 through V10.1 for AIX</td>
<td><a href="http://www.boost.org/doc/libs/1_41_0/libs/multi_index/doc/compiler_specifics.html#xl_90">Boost 1.41</a></td>
<td>November 2009</td>
</tr>
<tr>
<td>Intel C++ Compiler for Linux 8.1 through 11.1</td>
<td><a href="http://www.boost.org/doc/libs/1_41_0/libs/multi_index/doc/compiler_specifics.html#intel_81_lin">Boost 1.41</a></td>
<td>November 2009</td>
</tr>
<tr class="odd_tr">
<td>Intel C++ Compiler for Mac OS 9.1 through 11.0</td>
<td><a href="http://www.boost.org/doc/libs/1_41_0/libs/multi_index/doc/compiler_specifics.html#intel_91_mac">Boost 1.41</a></td>
<td>November 2009</td>
</tr>
<tr>
<td>Intel C++ Compiler for Windows 32-bit 8.0 through 11.1</td>
<td><a href="http://www.boost.org/doc/libs/1_41_0/libs/multi_index/doc/compiler_specifics.html#intel_80_win">Boost 1.41</a></td>
<td>November 2009</td>
</tr>
<tr class="odd_tr">
<td>Intel C++ Compiler for Windows 64-bit 10.0 through 11.11</td>
<td><a href="http://www.boost.org/doc/libs/1_41_0/libs/multi_index/doc/compiler_specifics.html#intel_100_win64">Boost 1.41</a></td>
<td>November 2009</td>
</tr>
<tr>
<td>Metrowerks CodeWarrior 8.3</td>
<td><a href="http://www.boost.org/doc/libs/1_36_0/libs/multi_index/doc/compiler_specifics.html#cw_83">Boost 1.36</a></td>
<td>August 2008</td>
</tr>
<tr class="odd_tr">
<td>Metrowerks CodeWarrior 9 through 9.5</td>
<td><a href="http://www.boost.org/doc/libs/1_34_1/libs/multi_index/doc/compiler_specifics.html#cw_9x">Boost 1.34.1</a></td>
<td>July 2007</td>
</tr>
<tr>
<td>Microsoft Visual C++ 6.0 Service Pack 5</td>
<td><a href="http://www.boost.org/doc/libs/1_36_0/libs/multi_index/doc/compiler_specifics.html#msvc_60">Boost 1.36</a></td>
<td>August 2008</td>
</tr>
<tr class="odd_tr">
<td>Microsoft Visual C++ 7.0</td>
<td><a href="http://www.boost.org/doc/libs/1_35_0/libs/multi_index/doc/compiler_specifics.html#msvc_70">Boost 1.35</a></td>
<td>March 2008</td>
</tr>
<tr>
<td>Sun Studio 10 through 12 Update 1 for Solaris</td>
<td><a href="http://www.boost.org/doc/libs/1_41_0/libs/multi_index/doc/compiler_specifics.html#sun_10">Boost 1.41</a></td>
<td>November 2009</td>
</tr>
</table>
</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 August 20th 2014</p>
<p>&copy; Copyright 2003-2014 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>
+7 -7
View File
@@ -105,7 +105,7 @@ See <a href="../example/bimap.cpp">source code</a>.
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 <code>(const FromType,const ToType)</code> pairs
such that no two elements exists with the same first
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
@@ -174,9 +174,9 @@ 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>
@@ -222,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>
@@ -450,9 +450,9 @@ Tests
<br>
<p>Revised May 26th 2009</p>
<p>Revised November 18th 2019</p>
<p>&copy; Copyright 2003-2009 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">
+2 -3
View File
@@ -67,7 +67,6 @@ examples of use developed in the documentation:
<ul>
<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>
@@ -86,9 +85,9 @@ Tutorial
<br>
<p>Revised April 19th 2015</p>
<p>Revised November 7th 2025</p>
<p>&copy; Copyright 2003-2015 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">
+14 -14
View File
@@ -6,7 +6,7 @@
<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="compiler_specifics.html">
<link rel="prev" href="reference/key_extraction.html">
<link rel="up" href="index.html">
<link rel="next" href="examples.html">
</head>
@@ -15,8 +15,8 @@
<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
@@ -111,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>
@@ -220,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>
@@ -230,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.
@@ -247,7 +247,7 @@ the space allocated per element in a manual simulation is
<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>
@@ -285,7 +285,7 @@ Taking this fact into account, the former formula can be adjusted to:
<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.)
is the system word size (typically 4 bytes on 32-bit architectures).
</p>
<p>
@@ -473,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>
@@ -725,7 +725,7 @@ 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>
@@ -737,8 +737,8 @@ some improvements both in space consumption and execution time.
<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
@@ -749,9 +749,9 @@ Examples
<br>
<p>Revised November 24th 2015</p>
<p>Revised November 7th 2025</p>
<p>&copy; Copyright 2003-2015 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">
+252 -26
View File
@@ -199,9 +199,13 @@ together, with minor differences explicitly stated when they exist.
<p>
Except where noted or if the corresponding interface does not exist, hashed indices
(both unique and non-unique) satisfy the C++ requirements for unordered associative
containers at <b>[unord.req]</b> (supporting unique and equivalent keys, respectively.)
Validity of iterators and references to
elements is preserved in all cases. Occasionally, the exception safety guarantees provided
containers at <b>[unord.req]</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.
Occasionally, the exception safety guarantees provided
are actually stronger than required by the standard. We only provide descriptions of
those types and operations that do not exactly conform to or are not mandated by the standard
requirements.
@@ -240,6 +244,8 @@ requirements.
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>const_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>local_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>const_local_iterator</span><span class=special>;</span>
<span class=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/destroy/copy:</span>
@@ -280,6 +286,11 @@ requirements.
<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>
@@ -297,6 +308,16 @@ requirements.
<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>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>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>
@@ -323,6 +344,15 @@ requirements.
<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>CompatibleHash</span><span class=special>&amp;</span> <span class=identifier>hash</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatiblePred</span><span class=special>&amp;</span> <span class=identifier>eq</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&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>CompatibleHash</span><span class=special>,</span> <span class=keyword>typename</span> <span class=identifier>CompatiblePred</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>CompatibleHash</span><span class=special>&amp;</span> <span class=identifier>hash</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatiblePred</span><span class=special>&amp;</span> <span class=identifier>eq</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&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>
@@ -428,7 +458,7 @@ 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>Hash</code> is a
<code>CopyConstructible</code>unary function object
<code>CopyConstructible</code> unary function object
taking a single argument of type <code>KeyFromValue::result_type</code> and returning a
value of type <code>std::size_t</code> in the range
<code>[0, std::numeric_limits&lt;std::size_t&gt;::max())</code>.
@@ -454,7 +484,10 @@ local_iterator<br>
const_local_iterator</code>
<blockquote>
These types are forward iterators.
These types are forward iterators. They depend only on <code>node_type</code>,
the position of the index in the <code>multi_index_container</code>, and whether
the index is unique or not (this implies that, for instance, iterators to elements transferred
from a unique index to a non-unique one will become invalid).
</blockquote>
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
@@ -643,6 +676,86 @@ to which this index belongs if
</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, except that rehashing may occur even if the
operation fails. 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.<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, except that rehashing may occur even if the
operation fails.
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> Average case <code>O(1 + D(n))</code>, worst case
<code>O(n<sub>dist</sub> + D(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>iterator erase(iterator position);</code>
<blockquote>
@@ -661,7 +774,7 @@ if no such element exists.<br>
<blockquote>
<b>Effects:</b> Deletes the elements with key equivalent to <code>x</code>.<br>
<b>Returns:</b> Number of elements deleted.<br>
<b>Complexity:</b> Average case, <code>O(1 + m*D(n))</code>, worst case
<b>Complexity:</b> Average case <code>O(1 + m*D(n))</code>, worst case
<code>O(n<sub>dist</sub> + m*D(n))</code>, where <code>m</code> is
the number of elements deleted.<br>
<b>Exception safety:</b> Basic.<br>
@@ -689,7 +802,7 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<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>
the index belongs if, for the value <code>x</code>,
<ul>
<li>the index is non-unique OR no other element exists
(except possibly <code>*position</code>) with equivalent key,</li>
@@ -736,7 +849,7 @@ original value, the position of the element does not change.<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>
@@ -747,16 +860,13 @@ bool modify(iterator position,Modifier mod,Rollback back);</code>
<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.
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>.
The sequence of operations <code>mod(e)</code>,
<code>back(e)</code> restores all keys of the element
to their original state.<br>
<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
@@ -766,8 +876,9 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
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
@@ -775,8 +886,10 @@ original value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
<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.
@@ -817,9 +930,7 @@ 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>.
The sequence of operations <code>mod(k)</code>,
<code>back(k)</code> restores <code>k</code> to its original state.<br>
<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
@@ -827,6 +938,89 @@ with <code>mod'</code> and <code>back</code> defined in such a way that
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<code>template&lt;typename Index&gt; void merge(Index&amp;&amp; x);</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>.<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 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> 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>
<p>Apart from standard <code>hash_function</code> and <code>key_eq</code>,
@@ -960,6 +1154,35 @@ size_type count(<br>
<code>O(count(x,hash,eq)+n<sub>dist</sub>)</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>hasher</code>, <code>key_equal</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> Average case <code>O(1)</code> (constant), worst case
<code>O(n<sub>dist</sub>)</code>.<br>
</blockquote>
<code>template&lt;<br>
&nbsp;&nbsp;typename CompatibleKey,typename CompatibleHash, typename CompatiblePred<br>
&gt;<br>
bool contains(<br>
&nbsp;&nbsp;const CompatibleKey&amp; x,<br>
&nbsp;&nbsp;const CompatibleHash&amp; hash,const CompatiblePred&amp; eq)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleHash</code>,
<code>CompatiblePred</code>) is a compatible extension of
(<code>hasher</code>, <code>key_equal</code>).<br>
<b>Effects:</b> Returns <code>true</code> iff there is some element with key equivalent to <code>x</code>.<br>
<b>Complexity:</b> Average case <code>O(1)</code> (constant), worst case
<code>O(n<sub>dist</sub>)</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
std::pair&lt;iterator,iterator> equal_range(const CompatibleKey&amp; x)const;
</code>
@@ -1082,9 +1305,12 @@ Operation: loading of a <code>multi_index_container</code> <code>m'</code> from
input archive (XML archive) <code>ar</code>.
<blockquote>
<b>Requires:</b> Additionally to the general requirements, <code>key_eq()</code>
must be serialization-compatible with <code>m.get&lt;i&gt;().key_eq()</code>,
where <code>i</code> is the position of the hashed index in the container.<br>
<b>Requires:</b> Additionally to the general requirements, the binary predicate
<code><i>value_eq</i>(m'.get&lt;i&gt;())</code> must be serialization-compatible with
<code><i>value_eq</i>(m.get&lt;i&gt;())</code>, where
<code><i>value_eq</i>(c)(x,y)</code> is defined as
<code>c.key_eq()(c.key_extractor()(x),c.key_extractor()(y))</code>
and <code>i</code> is the position of the hashed index in the container.<br>
<b>Postconditions:</b> On successful loading, the range
[<code>begin()</code>, <code>end()</code>) contains restored copies of every
element in [<code>m.get&lt;i&gt;().begin()</code>, <code>m.get&lt;i&gt;().end()</code>),
@@ -1129,7 +1355,7 @@ then <code>*it'</code> is the restored copy of <code>*it</code>; if <code>it</co
was <code>m.get&lt;i&gt;().end(n)</code> for some <code>n</code>, then
<code>it'==m'.get&lt;i&gt;().end(n)</code> (where <code>m</code> is the original
<code>multi_index_container</code>, <code>m'</code> its restored copy
and <code>i</code> is the ordinal of the index.)<br>
and <code>i</code> is the ordinal of the index).<br>
<b>Note:</b> It is allowed that <code>it</code> be a <code>const_local_iterator</code>
and the restored <code>it'</code> a <code>local_iterator</code>, or vice versa.
</blockquote>
@@ -1148,9 +1374,9 @@ Sequenced indices
<br>
<p>Revised November 26th 2015</p>
<p>Revised March 15th 2024</p>
<p>&copy; Copyright 2003-2015 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2024 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">
+22 -39
View File
@@ -81,7 +81,7 @@ 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
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
@@ -103,7 +103,7 @@ 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 replacement and modification which allow for the mutation of elements
in a controlled fashion. Immutability of elements does not significantly
@@ -120,8 +120,8 @@ 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
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 satisfy the C++ requirements for
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>
@@ -156,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>
@@ -212,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>
@@ -223,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>
@@ -264,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>
@@ -280,25 +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>struct</span> <span class=identifier>tag</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
<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.
The nested
<code>type</code> is a model of
<a href="../../../../libs/mpl/doc/refmanual/random-access-sequence.html">
<code>MPL Random Access Sequence</code></a> and
<a href="../../../../libs/mpl/doc/refmanual/extensible-sequence.html">
<code>MPL Extensible Sequence</code></a> containing the types <code>T0</code>, ... ,
<code>Tn</code> in the same order as specified.
</p>
<h2><a name="index_catalog">Indices provided by Boost.MultiIndex</a></h2>
@@ -312,7 +295,7 @@ 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
@@ -336,7 +319,7 @@ reference</a>.
<h2><a name="views">Index views</a></h2>
<p>
The following concept is used by the rearrange facilities of non key-based
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
@@ -386,9 +369,9 @@ Ordered indices
<br>
<p>Revised April 19th 2015</p>
<p>Revised October 25th 2025</p>
<p>&copy; Copyright 2003-2015 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
+133 -53
View File
@@ -235,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>
@@ -264,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>
@@ -287,8 +287,9 @@ operators and functions associated with the index (vg. comparison and
<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>
@@ -304,6 +305,12 @@ operators and functions associated with the index (vg. comparison and
<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>
@@ -381,7 +388,7 @@ operators and functions associated with the index (vg. comparison and
<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=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>
@@ -392,7 +399,7 @@ operators and functions associated with the index (vg. comparison and
<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=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>
@@ -403,7 +410,7 @@ operators and functions associated with the index (vg. comparison and
<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=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>
@@ -414,7 +421,7 @@ operators and functions associated with the index (vg. comparison and
<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=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>
@@ -523,13 +530,10 @@ scheme outlined in the
</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.
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>.
@@ -548,13 +552,21 @@ scheme outlined in the
<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>
@@ -585,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>
@@ -608,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>
@@ -625,7 +644,7 @@ 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>
@@ -671,8 +690,16 @@ as an associated tag type.
<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; args_list=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>
@@ -701,7 +728,7 @@ multi_index_container(<br>
<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 and empty <code>multi_index_container</code> using the
<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
@@ -728,7 +755,7 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<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 (those specified
in <code>ctor_args_list</code> and the allocator.)<br>
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>.
@@ -738,16 +765,52 @@ of the <code>multi_index_container</code> is preserved as well.<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 moving the
<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>
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>
@@ -760,8 +823,12 @@ contained. The order in which the elements are destroyed is not specified.<br>
<blockquote>
<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 of the <code>multi_index_container</code>
with copies from <code>x</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>
@@ -775,14 +842,27 @@ of the types of <code>ctor_args_list</code> do not throw.
&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> and its internal objects with copies from the
corresponding objects in <code>x</code>.<br>
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>.<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>
@@ -793,7 +873,7 @@ of the types of <code>ctor_args_list</code> do not throw.
<blockquote>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Replaces the elements the <code>multi_index_container</code>
<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>
@@ -817,7 +897,7 @@ the <code>multi_index_container</code>.<br>
<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>
@@ -826,7 +906,7 @@ the <code>multi_index_container</code>.<br>
<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>
@@ -872,10 +952,10 @@ are <i>equivalent</i> if:
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>
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>
@@ -886,7 +966,7 @@ equivalent to <code>it</code>.<br>
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>
@@ -905,7 +985,7 @@ typename index&lt;Tag>::type::iterator project(IteratorType it);</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>
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>
@@ -921,7 +1001,7 @@ typename index&lt;Tag>::type::const_iterator project(IteratorType it)const;</cod
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>
(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>
@@ -963,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>
@@ -973,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>
@@ -992,9 +1072,9 @@ Index reference
<br>
<p>Revised October 12th 2013</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2013 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">
+241 -22
View File
@@ -42,6 +42,7 @@ Ranked 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>
@@ -195,9 +196,13 @@ together, with minor differences explicitly stated when they exist.
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.)
Accordingly, validity of iterators and references to elements is
preserved. We only provide descriptions of those types and operations that
(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>
@@ -237,6 +242,8 @@ do not exactly conform to or are not mandated by the standard requirements.
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>
@@ -282,6 +289,11 @@ do not exactly conform to or are not mandated by the standard requirements.
<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>
@@ -299,6 +311,16 @@ do not exactly conform to or are not mandated by the standard requirements.
<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>
@@ -318,6 +340,11 @@ do not exactly conform to or are not mandated by the standard requirements.
<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>
@@ -416,7 +443,7 @@ 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
<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
@@ -449,6 +476,16 @@ must be a model of <a href="key_extraction.html#key_extractors">
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>
@@ -635,10 +672,89 @@ to which this index belongs if
</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
<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
@@ -727,7 +843,7 @@ original value, the position of the element does not change.<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>
@@ -744,10 +860,7 @@ 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>.
The sequence of operations <code>mod(e)</code>,
<code>back(e)</code> restores all keys of the element
to their original state.<br>
<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
@@ -757,8 +870,9 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
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
@@ -766,8 +880,10 @@ original value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
<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.
@@ -808,9 +924,7 @@ 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>.
The sequence of operations <code>mod(k)</code>,
<code>back(k)</code> restores <code>k</code> to its original state.<br>
<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
@@ -818,6 +932,89 @@ with <code>mod'</code> and <code>back</code> defined in such a way that
<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 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> 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>
<p>Apart from standard <code>key_comp</code> and <code>value_comp</code>,
@@ -907,8 +1104,8 @@ is a compatible extension of <code>key_compare</code>.<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>
@@ -929,6 +1126,28 @@ is a compatible extension of <code>key_compare</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>
@@ -1105,7 +1324,7 @@ Operation: loading of an <code>iterator</code> or <code>const_iterator</code>
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>
@@ -1122,9 +1341,9 @@ Ranked indices
<br>
<p>Revised November 26th 2015</p>
<p>Revised February 5th 2022</p>
<p>&copy; Copyright 2003-2015 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">
+204 -81
View File
@@ -40,6 +40,7 @@ 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>
@@ -158,8 +159,12 @@ random access indices includes that of
<a href="seq_indices.html">sequenced indices</a>, with differences in
the complexity of the operations, plus extra operations for
positional access (<code>operator[]</code> and <code>at()</code>) and
for capacity handling. Validity of iterators and references to elements
is preserved in all operations, regardless of the capacity status.
for capacity handling.
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) regardless of the capacity status, 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>
@@ -173,7 +178,7 @@ plus the requirements for <code>std::list</code> specific list operations at
have <code>data</code> member functions.
</li>
<li>The complexity of some operations, notably insertion and deletion, differ
<li>The complexities of some operations, notably insertion and deletion, differ
from those of <code>std::vector</code>.
</li>
<li>Unlike as in <code>std::vector</code>, insertions into a random access index
@@ -181,8 +186,8 @@ plus the requirements for <code>std::list</code> specific list operations at
of the operations provided with respect to their analogues in
<code>std::vector</code>.
</li>
<li>Elements in a randon access index are not mutable, and can only be changed
by means of <a href="#replace"><code>replace</code></a> and
<li>Elements in a random access index are not mutable, and can only be changed
in place by means of <a href="#replace"><code>replace</code></a> and
<a href="#modify"><code>modify</code></a> member functions.
</li>
<li><code>push_front</code> and <code>pop_front</code> are provided for
@@ -211,14 +216,16 @@ plus the requirements for <code>std::list</code> specific list operations at
<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>
@@ -291,6 +298,9 @@ plus the requirements for <code>std::list</code> specific list operations at
<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>
@@ -307,10 +317,16 @@ plus the requirements for <code>std::list</code> specific list operations at
<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>
@@ -423,7 +439,7 @@ of the complexity formulas:
<p>
(<code>shl</code> and <code>rel</code> stand for <i>shift left</i> and
<i>relocate</i>, respectively.)
<i>relocate</i>, respectively).
</p>
<h4><a name="instantiation_types">Instantiation types</a></h4>
@@ -441,6 +457,16 @@ index specifier. Instantiations are dependent on the following types:
<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>
@@ -524,7 +550,7 @@ const_iterator iterator_to(const value_type&amp; x)const;</code>
<code>size()&lt;c</code>, back insertions happen in constant time (the
general case as described by
<a href="#complexity_signature"><code>i(n)</code></a> is <i>amortized</i>
constant time.)<br>
constant time).<br>
<b>Note:</b> Validity of iterators and references to elements
is preserved in all insertions, regardless of the capacity status.
</blockquote>
@@ -564,7 +590,7 @@ into <code>multi_index_container</code>.<br>
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>
@@ -645,7 +671,7 @@ is <code>true</code> if and only if insertion took place. On successful insertio
<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>Complexity:</b> <code>O(shl(end()-position,1) + I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
@@ -666,7 +692,7 @@ 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>Complexity:</b> <code>O(shl(end()-position,1) + I(n))</code>.<br>
<b>Exception safety:</b> Strong.
</blockquote>
@@ -712,6 +738,40 @@ where <code>m</code> is the number of elements in
</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(shl(end()-position,1) + 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>
@@ -783,7 +843,7 @@ 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>
@@ -800,24 +860,24 @@ 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>.
The sequence of operations <code>mod(e)</code>,
<code>back(e)</code> restores all keys of the element
to their original state.<br>
<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 and the
element is kept at its original position in all indices.<br>
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>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
<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.
@@ -832,56 +892,116 @@ The syntax and behavior of these operations exactly matches those
of sequenced indices, but the associated complexity bounds differ in general.
</p>
<code>void splice(iterator position,<b>index class name</b>&amp; x);</code>
<code>template&lt;typename Index&gt; void splice(const_iterator position,Index&amp;&amp; x);</code>
<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 successfully
inserted are erased from <code>x</code>.<br>
<b>Complexity:</b> <code>O(shl(end()-position,x.size()) + 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 successful, 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 successful. 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>, <code>O(rel(position,i,i+1))</code>;
otherwise <code>O(shl(end()-position,1) + 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,
<code>O(rel(position,i',i'+1))</code>, where <code>i'</code> is the projection
of <code>i</code> into the index of <code>position</code>;
otherwise, <code>O(shl(end()-position,1) + 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 successful,
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 successful.<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>,
<code>O(rel(position,first,last))</code>; otherwise
<code>O(shl(end()-position,m) + 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>, <code>O(rel(position,first,last))</code>;
else, if the source and destination containers are the same, <code>O(n)</code>;
otherwise, <code>O(shl(end()-position,m) + 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>
@@ -930,20 +1050,22 @@ 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&gt;</code> induces a
<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&gt;</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
<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>;
@@ -953,19 +1075,20 @@ otherwise, basic.<br>
<code>template &lt;typename Compare> void merge(index class name&amp; x,Compare comp);</code>
<blockquote>
<b>Requires:</b> <code>Compare</code> induces a
strict weak ordering 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>;
@@ -1100,7 +1223,7 @@ Operation: loading of an <code>iterator</code> or <code>const_iterator</code>
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>
@@ -1117,9 +1240,9 @@ Key extraction
<br>
<p>Revised November 26th 2015</p>
<p>Revised August 30th 2021</p>
<p>&copy; Copyright 2003-2015 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">
+77 -10
View File
@@ -42,6 +42,8 @@ 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="#set_operations">Set operations</a></li>
<li><a href="#rank_operations">Rank operations</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
@@ -173,16 +175,19 @@ explanations on their acceptable type values.
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">deletion</a>
is 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.
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: for the
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>
@@ -223,6 +228,8 @@ indices, bearing in mind the occasional differences in complexity.
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>
@@ -268,6 +275,11 @@ indices, bearing in mind the occasional differences in complexity.
<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>
@@ -285,6 +297,16 @@ indices, bearing in mind the occasional differences in complexity.
<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>
@@ -304,6 +326,11 @@ indices, bearing in mind the occasional differences in complexity.
<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>
@@ -435,8 +462,7 @@ 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: <code>h(n)=1</code> (constant) if the hint element
is immediately after the point of insertion, <code>h(n)=log(n)</code> otherwise,</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>
@@ -447,12 +473,12 @@ section</a>. The complexity signature of ranked indices is:
<p>
These complexity guarantees are the same as those of
<a href="ord_indices.html#complexity_signature">ordered indices</a>
except for deletion, which is <code>log(n)</code> here and amortized constant there.
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>Ordered indices are instantiated internally to <code>multi_index_container</code> and
<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
@@ -468,6 +494,47 @@ 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>
@@ -632,9 +699,9 @@ Hashed indices
<br>
<p>Revised May 4th 2015</p>
<p>Revised February 5th 2022</p>
<p>&copy; Copyright 2003-2015 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">
+200 -77
View File
@@ -40,6 +40,7 @@ Random access 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="#capacity">Capacity operations</a></li>
@@ -152,8 +153,12 @@ like <code>std::list</code>. Elements in a sequenced index are by default
sorted according to their order of insertion: this means that new elements
inserted through a different index of the <code>multi_index_container</code> are appended
to the end of the sequenced index. Additionally, the index allows for free
reordering of elements in the same vein as <code>std::list</code> does. Validity
of iterators and references to elements is preserved in all operations.
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>
@@ -172,7 +177,7 @@ most important differences are:
<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>
@@ -199,14 +204,16 @@ most important differences are:
<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>
@@ -274,6 +281,9 @@ most important differences are:
<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>
@@ -290,10 +300,16 @@ most important differences are:
<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>
@@ -411,6 +427,16 @@ index specifier. Instantiations are dependent on the following types:
<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>
@@ -499,7 +525,7 @@ into <code>multi_index_container</code>.<br>
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>
@@ -644,6 +670,40 @@ number of elements in [<code>first</code>,<code>last</code>).<br>
</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>
@@ -715,7 +775,7 @@ 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>
@@ -732,24 +792,24 @@ 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>.
The sequence of operations <code>mod(e)</code>,
<code>back(e)</code> restores all keys of the element
to their original state.<br>
<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 and the
element is kept at its original position in all indices.<br>
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>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
<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.
@@ -759,62 +819,122 @@ is rethrown.
<p>
Sequenced indices provide the full set of list operations found in
<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
<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 successfully
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 successful, 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 successful. 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 successful,
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 successful.<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>
@@ -863,20 +983,22 @@ 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&gt;</code> induces a
<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&gt;</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
<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>;
@@ -886,19 +1008,20 @@ otherwise, basic.<br>
<code>template &lt;typename Compare&gt; void merge(index class name&amp; x,Compare comp);</code>
<blockquote>
<b>Requires:</b> <code>Compare</code> induces a
strict weak ordering 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>;
@@ -1035,7 +1158,7 @@ Operation: loading of an <code>iterator</code> or <code>const_iterator</code>
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>
@@ -1052,9 +1175,9 @@ Random access indices
<br>
<p>Revised November 26th 2015</p>
<p>Revised August 30th 2021</p>
<p>&copy; Copyright 2003-2015 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">
+356 -5
View File
@@ -30,6 +30,27 @@ Acknowledgements
<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>
@@ -53,6 +74,337 @@ Acknowledgements
<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>
@@ -171,7 +523,7 @@ Acknowledgements
</li>
<li>Random access indices provide <code>shrink_to_fit()</code>.</li>
</ul>
Refer to the <a href="compiler_specifics.html">compiler specifics</a> section for limitations
Refer to the compiler specifics section for limitations
on pre-C++11 compilers.
</li>
<li>The following classes are deprecated:
@@ -490,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>
@@ -512,9 +863,9 @@ Acknowledgements
<br>
<p>Revised October 19th 2015</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2015 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)
+34 -22
View File
@@ -43,41 +43,50 @@ 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">
<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>
(non-key-based indices) and <code>reserve</code>/<code>capacity</code>
(random access indices only).</td>
</tr>
<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,
(non key-based 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>
@@ -92,47 +101,51 @@ 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 class="odd_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>
<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 class="odd_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>
<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>
<tr class="odd_tr">
<td><a href="../test/test_special_set_ops.cpp"><code>test_special_set_ops.cpp</code></a></td>
<td>Checks special lookup operations using compatible sorting criteria.</td>
</tr>
<tr class="odd_tr">
<tr>
<td><a href="../test/test_update.cpp"><code>test_update.cpp</code></a></td>
<td><code>replace</code>, <code>modify</code> and <code>modify_key</code>.</td>
</tr>
@@ -153,10 +166,9 @@ Future work
<br>
<p>Revised October 26th 2025</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2015 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">
+13 -15
View File
@@ -114,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
@@ -268,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>
@@ -417,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>
@@ -453,7 +453,7 @@ in the previous example can be rewritten to hold two different tags
<p>
Each index of a <code>multi_index_container</code> uses its own
iterator types, which are different from those of another indices. As is
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>
@@ -496,7 +496,7 @@ 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>
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).
@@ -505,11 +505,9 @@ Currently, Boost.MultiIndex provides the following index types:
<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 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>
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>
@@ -768,7 +766,7 @@ 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
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>.
@@ -803,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>
@@ -1231,7 +1229,7 @@ Appropriate instantiations of <code>multi_index_container</code> can in fact sim
<code>std::set</code>, <code>std::multiset</code> and (with more limitations)
<code>std::list</code>, as shown in the
<a href="techniques.html#emulate_std_containers">techniques</a>
section. These simulations are as nearly as efficient as the original STL
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
@@ -1252,9 +1250,9 @@ Index types
<br>
<p>Revised November 24th 2015</p>
<p>Revised August 16th 2021</p>
<p>&copy; Copyright 2003-2015 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">
+3 -3
View File
@@ -201,7 +201,7 @@ than strictly required by the C++ standard, as explained in detail in the
An important type of non-standard allocators supported are those provided by the
<a href="../../../interprocess/index.html">Boost Interprocess Library</a>;
this opens up the possibility of placing <code>multi_index_container</code>s
in shared memory.
and their iterators in shared memory.
</p>
<blockquote><pre>
@@ -340,9 +340,9 @@ Debugging support
<br>
<p>Revised July 17th 2007</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2007 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">
+28 -6
View File
@@ -34,6 +34,7 @@ Techniques
<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>
@@ -89,7 +90,7 @@ and functions of the library.
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/assert.html">
by default resolves to a call to <a href="../../../../libs/assert">
<code>BOOST_ASSERT</code></a>.
</p>
@@ -125,7 +126,8 @@ is one value of the <code>safe_mode::error_code</code> enumeration:
<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=comment>// containers ought to be different</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>
@@ -161,7 +163,7 @@ asserting:
</pre></blockquote>
<p>
Other possibilites, like outputting to a log or firing some kind of alert, are
Other possibilities, like outputting to a log or firing some kind of alert, are
also implementable.
</p>
@@ -198,6 +200,26 @@ checked value by using the following workaround:
<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>
@@ -213,7 +235,7 @@ internal invariants of the data structures managed are preserved.
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/assert.html">
<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
@@ -239,9 +261,9 @@ Techniques
<br>
<p>Revised July 16th 2014</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2014 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
@@ -101,7 +101,7 @@ indices are met.
<p>
All the public 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
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:
+115 -7
View File
@@ -55,13 +55,14 @@ Key extraction
</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 six different index types, which can be classified as
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;
@@ -282,7 +283,7 @@ determining whether a hashed index is preferred over an ordered one.
</p>
<p>
Hashed indices replicate the interface as <code>std::unordered_set</code> and
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.
@@ -354,7 +355,7 @@ in practice greatly reduces the freedom in choosing an equality predicate.
<p>
The lookup interface of hashed indices consists in member functions
<code>find</code>, <code>count</code> and <code>equal_range</code>.
<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>
@@ -655,7 +656,7 @@ 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::random_suffle</code> on an ad hoc view obtained from the
<code>std::shuffle</code> on an ad hoc view obtained from the
container:
</p>
@@ -756,7 +757,7 @@ specifically designed for handling the elements of a container,
and not only benefit from the iterator orientation of container interfaces,
but are also capable of exposing many more programming bugs than raw pointers, both
at compile and run time. <code>iterator_to</code> is thus meant to be used
in scenarios where access via iterators is not suitable or desireable:
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
@@ -774,6 +775,113 @@ in scenarios where access via iterators is not suitable or desireable:
</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>
@@ -821,9 +929,9 @@ Key extraction
<br>
<p>Revised August 19th 2015</p>
<p>Revised August 16th 2021</p>
<p>&copy; Copyright 2003-2015 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">
+180 -9
View File
@@ -39,8 +39,11 @@ Container creation
<ul>
<li><a href="#identity"><code>identity</code></a></li>
<li><a href="#member"><code>member</code></a></li>
<li><a href="#const_mem_fun"><code>const_mem_fun</code>
and <code>mem_fun</code></a></li>
<li><a href="#const_mem_fun"><code>const_mem_fun</code> and <code>mem_fun</code></a>
<ul>
<li><a href="#x_mem_fun">Variants for other types of member functions</a></li>
</ul>
</li>
<li><a href="#global_fun"><code>global_fun</code></a></li>
</ul>
</li>
@@ -50,6 +53,7 @@ Container creation
<li><a href="#composite_keys_hash">Composite keys and hashed indices</a></li>
</ul>
</li>
<li><a href="#key">C++17 terse key specification syntax</a></li>
<li><a href="#advanced_key_extractors">Advanced features of Boost.MultiIndex key
extractors</a></li>
</ul>
@@ -94,10 +98,10 @@ of the element and do not depend on external data.
A key extractor is called <i>read/write</i> if it returns a non-constant reference
to the key when passed a non-constant element, and it is called <i>read-only</i>
otherwise. Boost.MultiIndex requires that the key extractor be read/write
when using the <code>modify_key</code> member function of ordered and hashed
when using the <code>modify_key</code> member function of key-based
indices. In all other situations, read-only extractors suffice.
The section on <a href="#advanced_key_extractors">advanced features
of Boost.MultiIndex key extractors</a> details which of the predefined
of Boost.MultiIndex key extractors</a> shows typical situations on which the predefined
key extractors are read/write.
</p>
@@ -245,10 +249,97 @@ of Boost.MultiIndex key extractors</a>.
provides a complete program showing how to use <code>const_mem_fun</code>.
<p>
<h4><a name="x_mem_fun">Variants for other types of member functions</a></h4>
<p>
Consider the following, non-compiling code:
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>employee</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=identifier>salary</span><span class=special>()</span><span class=keyword>const</span><span class=special><b>&amp;</b>;</span> <span class=comment>// note the &amp;</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=special>...</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=comment>// compiler error: can't convert &amp;employee::salary to
// std::size_t (employee::*)() const</span>
<span class=identifier><b>const_mem_fun</b></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>salary</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>
The problem here is that the type of <code>&amp;employee::salary</code>, which is
<a href="https://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions">ref-qualified</a>,
does not match exactly what <code>const_mem_fun</code> expects. Fortunately, Boost.MultiIndex
provides a variant to fit:
</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=special>...</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=identifier><b>cref_mem_fun</b></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>salary</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>
This is the list of all available variants of <code>const_mem_fun</code> and
<code>mem_fun</code>:
</p>
<p align="center">
<table cellspacing="0">
<caption><b>Variants of <code>const_mem_fun</code> and <code>mem_fun</code>.</b></caption>
<tr>
<th>&nbsp;Member function example&nbsp;</th>
<th>Suitable extractor</th>
<th>Behaves as</th>
</tr>
<tr>
<td><code>int f()const volatile</code></td>
<td><a href="../reference/key_extraction.html#cv_mem_fun"><code>cv_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
<td align="center" rowspan="3">&nbsp;<code>const_mem_fun</code>&nbsp;</td>
</tr>
<tr>
<td><code>int f()const&amp;</code></td>
<td><a href="../reference/key_extraction.html#cv_mem_fun"><code>cref_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
</tr>
<tr>
<td><code>int f()const volatile&amp;</code></td>
<td><a href="../reference/key_extraction.html#cv_mem_fun"><code>cvref_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
</tr>
<tr>
<td><code>int f()volatile</code></td>
<td><a href="../reference/key_extraction.html#volatile_mem_fun"><code>volatile_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
<td align="center" rowspan="3"><code>mem_fun</code></td>
</tr>
<tr>
<td><code>int f()&amp;</code></td>
<td><a href="../reference/key_extraction.html#volatile_mem_fun"><code>ref_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
</tr>
<tr>
<td><code>int f()volatile&amp;</code></td>
<td><a href="../reference/key_extraction.html#volatile_mem_fun"><code>vref_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
</tr>
</table>
</p>
<h3><a name="global_fun"><code>global_fun</code></a></h3>
<p>
Whereas <code>const_mem_fun</code> and <code>mem_fun</code> are based on a
Whereas <code>const_mem_fun</code> and its variants are based on a
given member function of the base type from where the key is extracted,
<a href="../reference/key_extraction.html#global_fun"><code>global_fun</code></a>
takes a global function (or static member function) accepting the base
@@ -387,7 +478,7 @@ The analogous concept in Boost.MultiIndex is modeled by means of
<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=comment>//non-unique as some subscribers might have more than one number</span>
<span class=comment>// non-unique as some subscribers might have more than one number</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=identifier>composite_key</span><span class=special>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
@@ -403,7 +494,7 @@ The analogous concept in Boost.MultiIndex is modeled by means of
</pre></blockquote>
<p>
<code>composite_key</code> accepts two or more key extractors on the same
<code>composite_key</code> accepts several key extractors on the same
value (here, <code>phonebook_entry</code>). Lookup operations on a composite
key are accomplished by passing tuples with the values searched:
</p>
@@ -596,6 +687,86 @@ key depends on all of its elements, it is impossible to calculate it from
partial information.
</p>
<h2><a name="key">C++17 terse key specification syntax</a></h2>
<p>
C++17 introduces the declaration of <code>auto</code> template parameters, which can be
taken advantage of to eliminate some redundancy in the specification of Boost.MultiIndex
predefined key extractors. For instance, instead of the classical:
</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_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>
one can now write:
<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</span><span class=special>/</span><span class=identifier>key</span><span class=special>.</span><span class=identifier>hpp</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>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;&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier><b>key</b></span><span class=special><b>&lt;&amp;</b></span><span class=identifier><b>employee</b></span><span class=special><b>::</b></span><span class=identifier><b>name</b></span><span class=special><b>&gt;</b>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier><b>key</b></span><span class=special><b>&lt;&amp;</b></span><span class=identifier><b>employee</b></span><span class=special><b>::</b></span><span class=identifier><b>name_length</b></span><span class=special><b>&gt;</b>&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>
which results in the exact same defined type, as
<a href="../reference/key_extraction.html#key"><code>key</code></a> constructs are mere
aliases for the old syntax. <code>key</code> can be used to shorten the specification of
<a href="../reference/key_extraction.html#member"><code>member</code></a>,
<a href="../reference/key_extraction.html#const_mem_fun"><code>const_mem_fun</code></a>
(and <a href="../reference/key_extraction.html#cv_mem_fun">variants</a>),
<a href="../reference/key_extraction.html#mem_fun"><code>mem_fun</code></a>
(and <a href="../reference/key_extraction.html#volatile_mem_fun">variants</a>),
<a href="../reference/key_extraction.html#global_fun"><code>global_fun</code></a>
and, with additional terseness benefits,
<a href="../reference/key_extraction.html#composite_key"><code>composite_key</code></a>:
</p>
<blockquote><pre>
<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=comment>// composite key on family name and given name</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;
</span><span class=identifier><b>key</b></span><span class=special><b>&lt;&amp;</b></span><span class=identifier><b>phonebook_entry</b></span><span class=special><b>::</b></span><span class=identifier><b>family_name</b></span><span class=special><b>,&amp;</b></span><span class=identifier><b>phonebook_entry</b></span><span class=special><b>::</b></span><span class=identifier><b>given_name</b></span><span class=special><b>&gt;</b></span>
<span class=special>&gt;,</span>
<span class=comment>// unique index on phone number</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>key</span><span class=special>&lt;&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>phone_number</span><span class=special>&gt;&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>phonebook</span><span class=special>;</span>
</pre></blockquote>
In this example, the first usage of <code>key</code> substitutes for the
decidedly more cumbersome:
<blockquote><pre>
<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>
</pre></blockquote>
Note that we did not even have to specify the first <code>phonebook_entry</code>
argument: the internal machinery of <code>key</code> automatically deduces it for
us. Check the <a href="../reference/key_extraction.html#key_synopsis">reference</a>
for technical details.
<h2><a name="advanced_key_extractors">Advanced features of Boost.MultiIndex key
extractors</a></h2>
@@ -955,9 +1126,9 @@ Container creation
<br>
<p>Revised March 25th 2015</p>
<p>Revised November 1st 2025</p>
<p>&copy; Copyright 2003-2015 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">
+42 -38
View File
@@ -40,8 +40,8 @@ Boost.MultiIndex reference
</li>
<li><a href="#metaprogrammming">Metaprogramming and <code>multi_index_container</code></a>
<ul>
<li><a href="#mpl_analysis">MPL analysis</a></li>
<li><a href="#mpl_synthesis">MPL synthesis</a></li>
<li><a href="#analysis">Analysis</a></li>
<li><a href="#synthesis">Synthesis</a></li>
</ul>
</li>
</ul>
@@ -53,7 +53,7 @@ Boost.MultiIndex reference
containers</a></h3>
<p>
Academic movitations aside, there is a practical interest in emulating standard
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.
@@ -266,11 +266,10 @@ or, if the default value <code>Allocator=std::allocator&lt;T></code> is used:
<p>
Boost.MultiIndex provides a number of facilities intended to allow the analysis and
synthesis of <code>multi_index_container</code> instantiations by
<a href="../../../../libs/mpl/doc/index.html">MPL</a> metaprograms.
synthesis of <code>multi_index_container</code> instantiations with metaprogramming.
</p>
<h3><a name="mpl_analysis">MPL analysis</a></h3>
<h3><a name="analysis">Analysis</a></h3>
<p>
Given a <code>multi_index_container</code> instantiation, the following nested types are
@@ -282,39 +281,47 @@ definition of the <code>multi_index_container</code>:
<li><code>iterator_type_list</code>,</li>
<li><code>const_iterator_type_list</code>.</li>
</ul>
Each of these types is an MPL sequence with as many elements as indices
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>.
</p>
<p>
A subtle but important distinction exists between
<code>index_specifier_type_list</code> and <code>index_type_list</code>:
the former typelist 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. An example will help to clarify
this distinction. Given the instantiation:
<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>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<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>indexed_t</span><span class=special>;</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>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>
@@ -328,21 +335,18 @@ while <code>indexed_t::index_type_list</code> holds the types
</pre></blockquote>
<p>
so the typelists are radically different. Check the
<a href="../reference/multi_index_container.html#types">reference</a>
for the exact MPL sequence concepts modeled by these type lists.
so the lists are radically different.
</p>
<h3><a name="mpl_synthesis">MPL synthesis</a></h3>
<h3><a name="synthesis">Synthesis</a></h3>
<p>
Although typically indices are specified by means of the
<code>indexed_by</code> construct, actually any MPL sequence of
index specifiers can be provided instead:
<code>indexed_by</code> construct, actually any Mp11 list can be provided instead:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>mpl</span><span class=special>::</span><span class=identifier>vector</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=identifier>index_list_t</span><span class=special>;</span>
<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>
@@ -352,30 +356,30 @@ index specifiers can be provided instead:
<p>
This possibility enables the synthesis of instantiations of
<code>multi_index_container</code> through MPL metaprograms, as the following
<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>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</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=identifier>indexed_t1</span><span class=special>;</span>
<span class=special>&gt;;</span>
<span class=comment>// we take its index list and add an index</span>
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>push_front</span><span class=special>&lt;</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=identifier>type</span> <span class=identifier>index_list_t</span><span class=special>;</span>
<span class=special>&gt;;</span>
<span class=comment>// augmented multi_index_container</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</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_t</span>
<span class=special>&gt;</span> <span class=identifier>indexed_t2</span><span class=special>;</span>
<span class=identifier>index_list_t2</span>
<span class=special>&gt;;</span>
</pre></blockquote>
<hr>
@@ -392,9 +396,9 @@ Boost.MultiIndex reference
<br>
<p>Revised November 7th 2008</p>
<p>Revised October 25th 2025</p>
<p>&copy; Copyright 2003-2008 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">
+10 -13
View File
@@ -1,69 +1,66 @@
# Boost.MultiIndex examples Jamfile
#
# Copyright 2003-2007 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.
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
: <include>$(BOOST_ROOT)
;
exe hashed
: hashed.cpp
: <include>$(BOOST_ROOT)
/boost/tokenizer//boost_tokenizer
;
exe ip_allocator
: ip_allocator.cpp
: <include>$(BOOST_ROOT) <threading>multi
/boost/interprocess//boost_interprocess
: <threading>multi
;
exe non_default_ctor
: non_default_ctor.cpp
: <include>$(BOOST_ROOT)
;
exe random_access
: random_access.cpp
: <include>$(BOOST_ROOT)
/boost/tokenizer//boost_tokenizer
;
exe rearrange
: rearrange.cpp
: <include>$(BOOST_ROOT)
/boost/random//boost_random
;
exe sequenced
: sequenced.cpp
: <include>$(BOOST_ROOT)
/boost/tokenizer//boost_tokenizer
;
exe serialization
: serialization.cpp
/boost/serialization//boost_serialization
: <include>$(BOOST_ROOT)
;
+5 -9
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex basic example.
*
* Copyright 2003-2013 Joaquin M Lopez Munoz.
* 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,11 +57,11 @@ 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>
+1 -45
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of a bidirectional map.
*
* Copyright 2003-2009 Joaquin M Lopez Munoz.
* 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)
@@ -44,30 +44,6 @@ struct bidirectional_map
ToType 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
/* A bidirectional map can be simulated as a multi_index_container
* of pairs of (FromType,ToType) with two unique indices, one
* for each member of the pair.
@@ -82,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 */
@@ -108,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<dictionary,1>::type::iterator it2=get<1>(d).find(word);
if(it2!=get<1>(d).end()){
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
}
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);
@@ -143,7 +101,5 @@ int main()
else std::cout<<"No such word in the dictionary"<<std::endl;
}
#endif
return 0;
}
+12 -16
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example: complex searches and foreign keys.
*
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* 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>
>
>
>
+7 -11
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of composite keys.
*
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* 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)
@@ -57,26 +57,22 @@ 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<
+2 -4
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of functions used as key extractors.
*
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* 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)
@@ -54,15 +54,13 @@ std::string::size_type name_record_length(const name_record& r)
/* multi_index_container with indices based on name_record::name()
* and name_record_length().
* See Compiler specifics: Use of const_mem_fun_explicit and
* mem_fun_explicit for info on BOOST_MULTI_INDEX_CONST_MEM_FUN.
*/
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>
+15 -19
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of hashed indices.
*
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* 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;
@@ -70,23 +66,23 @@ int main()
std::string text=
"En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha "
"mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga "
"antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que "
"carnero, salpicón las más noches, duelos y quebrantos los sábados, "
"lantejas los viernes, algún palomino de añadidura los domingos, "
"consumían las tres partes de su hacienda. El resto della concluían sayo "
"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 */
+4 -9
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of Boost.Interprocess allocators.
*
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* 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)
@@ -10,7 +10,6 @@
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
@@ -104,22 +103,18 @@ struct partial_str_less
* * We are using a Boost.Interprocess specific allocator.
*/
/* see Compiler specifics: Use of member_offset for info on
* BOOST_MULTI_INDEX_MEMBER
*/
typedef multi_index_container<
book,
indexed_by<
ordered_non_unique<
BOOST_MULTI_INDEX_MEMBER(book,shared_string,author)
member<book,shared_string,&book::author>
>,
ordered_non_unique<
BOOST_MULTI_INDEX_MEMBER(book,shared_string,name),
member<book,shared_string,&book::name>,
partial_str_less
>,
ordered_non_unique<
BOOST_MULTI_INDEX_MEMBER(book,unsigned,prize)
member<book,unsigned,&book::prize>
>
>,
bip::allocator<book,bip::managed_mapped_file::segment_manager>
+6 -20
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of rearrange facilities.
*
* Copyright 2003-2015 Joaquin M Lopez Munoz.
* 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,7 +14,6 @@
#endif
#include <boost/config.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/random/binomial_distribution.hpp>
@@ -23,11 +22,8 @@
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#if !defined(BOOST_NO_CXX11_HDR_RANDOM)
#include <random>
#endif
#include <vector>
using boost::multi_index_container;
using namespace boost::multi_index;
@@ -140,11 +136,11 @@ void riffle_shuffle(
{
static boost::mt19937 rnd_gen;
typedef typename boost::detail::iterator_traits<
RandomAccessIterator>::difference_type difference_type;
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;
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);
@@ -198,22 +194,12 @@ struct random_shuffler
private:
deck_view dv;
#if !defined(BOOST_NO_CXX11_HDR_RANDOM)
std::mt19937 e;
void shuffle_view()
{
std::shuffle(dv.begin(),dv.end(),e);
}
#else
/* for pre-C++11 compilers we use std::random_shuffle */
void shuffle_view()
{
std::random_shuffle(dv.begin(),dv.end());
}
#endif
};
/* Repeat a given shuffling algorithm repeats_num times
File diff suppressed because it is too large Load Diff
@@ -1,54 +0,0 @@
/* 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_ACCESS_SPECIFIER_HPP
#define BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP
#if defined(_MSC_VER)
#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.
* Sun Studio also has this problem, which might be related, from the
* information gathered at Sun forums, with a known issue notified at the
* internal bug report 6421933. The bug is present up to Studio Express 2,
* the latest preview version of the future Sun Studio 12. As of this writing
* (October 2006) it is not known whether a fix will finally make it into the
* official Sun Studio 12.
*/
#if BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\
BOOST_WORKAROUND(BOOST_MSVC,==1310)||\
BOOST_WORKAROUND(BOOST_MSVC,==1400)||\
BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590))
#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS public
#else
#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS private
#endif
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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)
@@ -25,14 +25,8 @@ namespace detail{
template<typename T>
void adl_swap(T& x,T& y)
{
#if !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
using std::swap;
swap(x,y);
#else
std::swap(x,y);
#endif
}
} /* namespace multi_index::detail */
@@ -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-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -14,9 +14,9 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#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>
@@ -34,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();
}
@@ -48,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();
@@ -64,8 +64,12 @@ struct archive_constructed:private noncopyable
(&get())->~T();
}
#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:
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
};
@@ -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
+29 -17
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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)
@@ -15,9 +15,10 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/multi_index/detail/adl_swap.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <memory>
namespace boost{
@@ -45,18 +46,15 @@ namespace detail{
template<typename T,typename Allocator=std::allocator<T> >
struct auto_space:private noncopyable
{
typedef typename boost::detail::allocator::rebind_to<
Allocator,T
>::type::pointer pointer;
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(),std::size_t n=1):
al_(al),n_(n),data_(n_?al_.allocate(n_):pointer(0))
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_);}
Allocator get_allocator()const{return al_;}
@@ -64,16 +62,30 @@ struct auto_space:private noncopyable
void swap(auto_space& x)
{
if(al_!=x.al_)adl_swap(al_,x.al_);
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_;
pointer 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
+20 -29
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,10 +14,9 @@
#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/static_assert.hpp>
@@ -28,39 +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.
*/
struct index_applier
{
template<typename IndexSpecifierMeta,typename SuperMeta>
struct apply
{
typedef typename IndexSpecifierMeta::type index_specifier;
typedef typename index_specifier::
BOOST_NESTED_TEMPLATE index_class<SuperMeta>::type type;
};
};
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);
};
@@ -1,4 +1,4 @@
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
/* 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)
@@ -14,11 +14,11 @@
#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/serialization/nvp.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/core/serialization.hpp>
#endif
namespace boost{
@@ -36,7 +36,7 @@ class bidir_node_iterator:
public bidirectional_iterator_helper<
bidir_node_iterator<Node>,
typename Node::value_type,
std::ptrdiff_t,
typename Node::difference_type,
const typename Node::value_type*,
const typename Node::value_type&>
{
@@ -67,23 +67,27 @@ public:
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
*/
BOOST_SERIALIZATION_SPLIT_MEMBER()
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=node;
ar<<serialization::make_nvp("pointer",bnode);
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>>serialization::make_nvp("pointer",bnode);
node=static_cast<Node*>(bnode);
ar>>core::make_nvp("pointer",bnode);
node=typename Node::pointer(static_cast<Node*>(bnode));
}
#endif
@@ -91,10 +95,10 @@ public:
typedef Node node_type;
Node* get_node()const{return node;}
Node* get_node()const{return raw_ptr<Node*>(node);}
private:
Node* node;
typename Node::pointer node;
};
template<typename Node>
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -15,9 +15,10 @@
#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>
@@ -26,8 +27,8 @@
#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
@@ -128,10 +129,10 @@ class bucket_array:bucket_array_base<>
{
typedef bucket_array_base<> super;
typedef hashed_index_base_node_impl<
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
Allocator,
char
>::type
>
> base_node_impl_type;
public:
@@ -140,7 +141,7 @@ public:
bucket_array(const Allocator& al,pointer end_,std::size_t size_):
size_index_(super::size_index(size_)),
spc(al,super::sizes[size_index_]+1)
spc(al,static_cast<auto_space_size_type>(super::sizes[size_index_]+1))
{
clear(end_);
}
@@ -172,9 +173,19 @@ public:
spc.swap(x.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);
}
private:
std::size_t size_index_;
auto_space<base_node_impl_type,Allocator> spc;
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
{
@@ -213,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
@@ -1,4 +1,4 @@
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
/* 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,7 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/if.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/tuple/tuple.hpp>
#include <tuple>
@@ -55,11 +55,11 @@ struct cons_stdtuple_ctor_normal
template<typename StdTuple,std::size_t N=0>
struct cons_stdtuple_ctor:
boost::mpl::if_c<
mp11::mp_if_c<
N<std::tuple_size<StdTuple>::value,
cons_stdtuple_ctor_normal<StdTuple,N>,
cons_stdtuple_ctor_terminal
>::type
>
{};
template<typename StdTuple,std::size_t N>
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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)
@@ -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);
}
+65 -41
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -15,12 +15,14 @@
#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/multi_index/detail/raw_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <cstddef>
#include <functional>
#include <utility>
namespace boost{
@@ -54,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)
{}
@@ -69,8 +87,9 @@ public:
~copy_map()
{
if(!released){
for(std::size_t i=0;i<n;++i){
boost::detail::allocator::destroy(&(spc.data()+i)->second->value());
for(size_type i=0;i<n;++i){
allocator_destroy(
al_,boost::addressof((spc.data()+i)->second->value()));
deallocate((spc.data()+i)->second);
}
}
@@ -79,27 +98,8 @@ public:
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=raw_ptr<Node*>(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(
raw_ptr<copy_map_entry<Node>*>(spc.data()),
raw_ptr<copy_map_entry<Node>*>(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
{
@@ -114,22 +114,46 @@ public:
}
private:
typedef typename boost::detail::allocator::rebind_to<
Allocator,Node
>::type allocator_type;
typedef typename allocator_type::pointer allocator_pointer;
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;
allocator_type al_;
std::size_t size_;
auto_space<copy_map_entry<Node>,Allocator> spc;
std::size_t n;
Node* header_org_;
Node* header_cpy_;
bool released;
pointer allocate()
{
return allocator_allocate(al_,1);
}
void deallocate(Node* node)
{
al_.deallocate(static_cast<allocator_pointer>(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_);
}
}
};
@@ -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
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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)
@@ -14,7 +14,6 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <cstddef>
#include <iterator>
namespace boost{
@@ -32,7 +31,7 @@ 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;
+4 -6
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,7 +14,7 @@
#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-2013 Joaquin M Lopez Munoz.
/* 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,15 +14,13 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/functional/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{
@@ -46,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-2014 Joaquin M Lopez Munoz.
/* 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)
@@ -14,12 +14,11 @@
#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/serialization/nvp.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/version.hpp>
#include <boost/core/serialization.hpp>
#endif
namespace boost{
@@ -34,12 +33,15 @@ namespace detail{
struct hashed_index_global_iterator_tag{};
struct hashed_index_local_iterator_tag{};
template<typename Node,typename BucketArray,typename Category>
template<
typename Node,typename BucketArray,
typename IndexCategory,typename IteratorCategory
>
class hashed_index_iterator:
public forward_iterator_helper<
hashed_index_iterator<Node,BucketArray,Category>,
hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory>,
typename Node::value_type,
std::ptrdiff_t,
typename Node::difference_type,
const typename Node::value_type*,
const typename Node::value_type&>
{
@@ -55,7 +57,7 @@ public:
hashed_index_iterator& operator++()
{
this->increment(Category());
this->increment(IteratorCategory());
return *this;
}
@@ -64,21 +66,25 @@ public:
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
*/
BOOST_SERIALIZATION_SPLIT_MEMBER()
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=node;
ar<<serialization::make_nvp("pointer",bnode);
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,Category());
load(ar,version,IteratorCategory());
}
template<class Archive>
@@ -86,11 +92,11 @@ public:
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>>core::make_nvp("pointer",bnode);
node=typename Node::pointer(static_cast<Node*>(bnode));
if(version<1){
BucketArray* throw_away; /* consume unused ptr */
ar>>serialization::make_nvp("pointer",throw_away);
ar>>core::make_nvp("pointer",throw_away);
}
}
@@ -99,14 +105,14 @@ public:
Archive& ar,const unsigned int version,hashed_index_local_iterator_tag)
{
node_base_type* bnode;
ar>>serialization::make_nvp("pointer",bnode);
node=static_cast<Node*>(bnode);
ar>>core::make_nvp("pointer",bnode);
node=typename Node::pointer(static_cast<Node*>(bnode));
if(version<1){
BucketArray* buckets;
ar>>serialization::make_nvp("pointer",buckets);
if(buckets&&node&&node->impl()==buckets->end()->prior()){
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=0;
node=typename Node::pointer(0);
}
}
}
@@ -116,27 +122,32 @@ public:
typedef Node node_type;
Node* get_node()const{return node;}
Node* get_node()const{return raw_ptr<Node*>(node);}
private:
void increment(hashed_index_global_iterator_tag)
{
Node::increment(node);
Node::template increment<IndexCategory>(node);
}
void increment(hashed_index_local_iterator_tag)
{
Node::increment_local(node);
Node::template increment_local<IndexCategory>(node);
}
Node* node;
typename Node::pointer node;
};
template<typename Node,typename BucketArray,typename Category>
template<
typename Node,typename BucketArray,
typename IndexCategory,typename IteratorCategory
>
bool operator==(
const hashed_index_iterator<Node,BucketArray,Category>& x,
const hashed_index_iterator<Node,BucketArray,Category>& y)
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();
}
@@ -151,9 +162,14 @@ bool operator==(
*/
namespace serialization {
template<typename Node,typename BucketArray,typename Category>
template<
typename Node,typename BucketArray,
typename IndexCategory,typename IteratorCategory
>
struct version<
boost::multi_index::detail::hashed_index_iterator<Node,BucketArray,Category>
boost::multi_index::detail::hashed_index_iterator<
Node,BucketArray,IndexCategory,IteratorCategory
>
>
{
BOOST_STATIC_CONSTANT(int,value=1);
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -14,7 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/allocator_utilities.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <utility>
@@ -99,24 +99,17 @@ struct hashed_index_node_impl;
template<typename Allocator>
struct hashed_index_base_node_impl
{
typedef typename
boost::detail::allocator::rebind_to<
Allocator,hashed_index_base_node_impl
>::type::pointer base_pointer;
typedef typename
boost::detail::allocator::rebind_to<
typedef allocator_rebind_t<
Allocator,hashed_index_base_node_impl
>::type::const_pointer const_base_pointer;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
hashed_index_node_impl<Allocator>
>::type::pointer pointer;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
hashed_index_node_impl<Allocator>
>::type::const_pointer const_pointer;
> 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;
pointer& prior(){return prior_;}
pointer prior()const{return prior_;}
@@ -413,7 +406,7 @@ struct hashed_index_node_alg<Node,hashed_non_unique_tag>
buc->prior()=x;
x->next()->prior()=x;
}
};
}
static void link(pointer x,pointer first,pointer last)
{
@@ -694,20 +687,18 @@ private:
template<typename Super>
struct hashed_index_node_trampoline:
hashed_index_node_impl<
typename boost::detail::allocator::rebind_to<
typename Super::allocator_type,
char
>::type
allocator_rebind_t<
typename Super::allocator_type,char
>
>
{
typedef typename boost::detail::allocator::rebind_to<
typename Super::allocator_type,
char
>::type impl_allocator_type;
typedef hashed_index_node_impl<impl_allocator_type> impl_type;
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,typename Category>
template<typename Super>
struct hashed_index_node:
Super,hashed_index_node_trampoline<Super>
{
@@ -716,12 +707,23 @@ private:
public:
typedef typename trampoline::impl_type impl_type;
typedef hashed_index_node_alg<
impl_type,Category> node_alg;
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();}
@@ -758,14 +760,16 @@ public:
/* interoperability with hashed_index_iterator */
static void increment(hashed_index_node*& x)
template<typename Category>
static void increment(pointer& x)
{
x=from_impl(node_alg::after(x->impl()));
x=pointer(from_impl(node_alg<Category>::type::after(x->impl())));
}
static void increment_local(hashed_index_node*& x)
template<typename Category>
static void increment_local(pointer& x)
{
x=from_impl(node_alg::after_local(x->impl()));
x=pointer(from_impl(node_alg<Category>::type::after_local(x->impl())));
}
};
@@ -1,4 +1,4 @@
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
/* 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)
@@ -13,7 +13,7 @@
#pragma once
#endif
#include <boost/noncopyable.hpp>
#include <boost/core/noncopyable.hpp>
namespace boost{
@@ -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
+92 -58
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
/* 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)
@@ -14,16 +14,15 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/allocator_utilities.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.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/vartempl_support.hpp>
#include <boost/multi_index/detail/type_list.hpp>
#include <boost/multi_index_container_fwd.hpp>
#include <boost/tuple/tuple.hpp>
#include <utility>
@@ -55,42 +54,47 @@ template<typename Value,typename IndexSpecifierList,typename Allocator>
class index_base
{
protected:
typedef index_node_base<Value,Allocator> 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 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)
{}
@@ -102,7 +106,7 @@ protected:
{
x=final().allocate_node();
BOOST_TRY{
boost::detail::allocator::construct(&x->value(),v);
final().construct_value(x,v);
}
BOOST_CATCH(...){
final().deallocate_node(x);
@@ -116,14 +120,7 @@ protected:
{
x=final().allocate_node();
BOOST_TRY{
/* This shoud have used a modified, T&&-compatible version of
* boost::detail::allocator::construct, but
* <boost/detail/allocator_utilities.hpp> is too old and venerable to
* mess with; besides, it is a general internal utility and the imperfect
* perfect forwarding emulation of Boost.Move might break other libs.
*/
new (&x->value()) value_type(boost::move(const_cast<value_type&>(v)));
final().construct_value(x,std::move(const_cast<value_type&>(v)));
}
BOOST_CATCH(...){
final().deallocate_node(x);
@@ -138,55 +135,63 @@ protected:
return x;
}
template<typename MultiIndexContainer>
final_node_type* insert_(
const value_type& v,node_type*,final_node_type*& x,lvalue_tag)
const value_type&,final_node_type*& x,MultiIndexContainer* p)
{
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,node_type*,final_node_type*& x,rvalue_tag)
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&,node_type*,final_node_type*& x,emplaced_tag)
const value_type&,index_node_type*,final_node_type*& x,emplaced_tag)
{
return x;
}
void erase_(node_type* x)
{
boost::detail::allocator::destroy(&x->value());
}
void delete_node_(node_type* x)
{
boost::detail::allocator::destroy(&x->value());
}
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 */)
{}
void swap_elements_(index_base<Value,IndexSpecifierList,Allocator>&){}
bool replace_(const value_type& v,node_type* x,lvalue_tag)
bool replace_(const value_type& v,index_node_type* x,lvalue_tag)
{
x->value()=v;
return true;
}
bool replace_(const value_type& v,node_type* x,rvalue_tag)
bool replace_(const value_type& v,index_node_type* x,rvalue_tag)
{
x->value()=boost::move(const_cast<value_type&>(v));
x->value()=std::move(const_cast<value_type&>(v));
return true;
}
bool modify_(node_type*){return true;}
bool modify_(index_node_type*){return true;}
bool modify_rollback_(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 */
@@ -209,11 +214,15 @@ 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_(const value_type& x)
{return final().insert_(x);}
@@ -225,12 +234,17 @@ protected:
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<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<final_node_type*,bool> final_emplace_(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
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_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return final().emplace_(std::forward<Args>(args)...);
}
std::pair<final_node_type*,bool> final_insert_(
@@ -247,21 +261,41 @@ protected:
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<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
template<typename... Args>
std::pair<final_node_type*,bool> final_emplace_hint_(
final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
final_node_type* position,Args&&... args)
{
return final().emplace_hint_(
position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
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);}
void final_delete_node_(final_node_type* x){final().delete_node_(x);}
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_(
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -15,11 +15,11 @@
#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/multi_index/detail/bad_archive_exception.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/throw_exception.hpp>
#include <cstddef>
@@ -30,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.
*/
@@ -47,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
@@ -102,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);
}
@@ -110,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);
}
@@ -118,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-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -15,7 +15,7 @@
#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>
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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,8 +18,8 @@
#include <boost/type_traits/alignment_of.hpp>
#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
@@ -49,6 +49,8 @@ struct index_node_base:private pod_value_holder<Value>
typedef Value value_type;
typedef Allocator allocator_type;
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
value_type& value()
{
return *reinterpret_cast<value_type*>(&this->space);
@@ -59,6 +61,8 @@ struct index_node_base:private pod_value_holder<Value>
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 *>(
@@ -101,28 +105,19 @@ Node* node_from_value(const Value* p)
* somehow invalid archive.
*/
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
namespace serialization{
#else
namespace multi_index{
namespace detail{
#endif
template<class Archive,typename Value,typename Allocator>
inline void load_construct_data(
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,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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)
@@ -15,8 +15,8 @@
#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
@@ -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-2013 Joaquin M Lopez Munoz.
/* 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,8 +14,46 @@
#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
@@ -1,4 +1,4 @@
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
/* 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,8 +14,8 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/intrinsics.hpp>
#include <type_traits>
namespace boost{
@@ -29,7 +29,7 @@ namespace detail{
*/
template<typename F,typename Arg1,typename Arg2,typename=void>
struct is_transparent:mpl::true_{};
struct is_transparent:std::true_type{};
} /* namespace multi_index::detail */
@@ -37,21 +37,17 @@ struct is_transparent:mpl::true_{};
} /* namespace boost */
#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_SFINAE_EXPR)&& \
!defined(BOOST_NO_CXX11_DECLTYPE)&& \
#if !defined(BOOST_NO_SFINAE_EXPR)&& \
(defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL))
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/or.hpp>
#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>
#include <boost/utility/declval.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost{
@@ -70,7 +66,7 @@ struct is_transparent_class_helper:F
};
template<typename F,typename Arg1,typename Arg2,typename=void>
struct is_transparent_class:mpl::true_{};
struct is_transparent_class:std::true_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent_class<
@@ -84,38 +80,31 @@ struct is_transparent_class<
not_is_transparent_result_type
>
>::type
>:mpl::false_{};
>:std::false_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent<
F,Arg1,Arg2,
typename enable_if<
mpl::and_<
is_class<F>,
mpl::not_<is_final<F> > /* is_transparent_class_helper derives from F */
>
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:mpl::true_{};
struct is_transparent_function:std::true_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent_function<
F,Arg1,Arg2,
typename enable_if<
mpl::or_<
mpl::not_<mpl::or_<
is_same<typename function_traits<F>::arg1_type,const Arg1&>,
is_same<typename function_traits<F>::arg1_type,Arg1>
> >,
mpl::not_<mpl::or_<
is_same<typename function_traits<F>::arg2_type,const Arg2&>,
is_same<typename function_traits<F>::arg2_type,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
>:mpl::false_{};
>:std::false_type{};
template<typename F,typename Arg1,typename Arg2>
struct is_transparent<
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,7 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/apply.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/operators.hpp>
namespace boost{
@@ -125,10 +125,7 @@ template<>
struct iter_adaptor_selector<std::forward_iterator_tag>
{
template<class Derived,class Base>
struct apply
{
typedef forward_iter_adaptor_base<Derived,Base> type;
};
using fn=forward_iter_adaptor_base<Derived,Base>;
};
template<class Derived,class Base>
@@ -183,10 +180,7 @@ template<>
struct iter_adaptor_selector<std::bidirectional_iterator_tag>
{
template<class Derived,class Base>
struct apply
{
typedef bidirectional_iter_adaptor_base<Derived,Base> type;
};
using fn=bidirectional_iter_adaptor_base<Derived,Base>;
};
template<class Derived,class Base>
@@ -283,23 +277,17 @@ template<>
struct iter_adaptor_selector<std::random_access_iterator_tag>
{
template<class Derived,class Base>
struct apply
{
typedef random_access_iter_adaptor_base<Derived,Base> type;
};
using fn=random_access_iter_adaptor_base<Derived,Base>;
};
template<class Derived,class Base>
struct iter_adaptor_base
{
typedef iter_adaptor_selector<
typename Base::iterator_category> selector;
typedef typename mpl::apply2<
selector,Derived,Base>::type type;
};
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>::type
class iter_adaptor:public iter_adaptor_base<Derived,Base>
{
protected:
iter_adaptor(){}
@@ -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
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,8 +14,8 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/fold.hpp>
#include <boost/mpl/set/set0.hpp>
#include <boost/mp11/algorithm.hpp>
#include <type_traits>
namespace boost{
@@ -25,68 +25,11 @@ namespace detail{
/* no_duplicate_tags check at compile-time that a tag list
* has no duplicate tags.
* The algorithm deserves some explanation: tags
* are sequentially inserted into a mpl::set if they were
* not already present. Due to the magic of mpl::set
* (mpl::has_key is contant time), this operation takes linear
* time, and even MSVC++ 6.5 handles it gracefully (other obvious
* solutions are quadratic.)
*/
struct duplicate_tag_mark{};
struct duplicate_tag_marker
{
template <typename MplSet,typename Tag>
struct apply
{
typedef mpl::s_item<
typename mpl::if_<mpl::has_key<MplSet,Tag>,duplicate_tag_mark,Tag>::type,
MplSet
> type;
};
};
template<typename TagList>
struct no_duplicate_tags
{
typedef typename mpl::fold<
TagList,
mpl::set0<>,
duplicate_tag_marker
>::type aux;
BOOST_STATIC_CONSTANT(
bool,value=!(mpl::has_key<aux,duplicate_tag_mark>::value));
};
/* Variant for an index list: duplication is checked
* across all the indices.
*/
struct duplicate_tag_list_marker
{
template <typename MplSet,typename Index>
struct apply:mpl::fold<
BOOST_DEDUCED_TYPENAME Index::tag_list,
MplSet,
duplicate_tag_marker>
{
};
};
template<typename IndexList>
struct no_duplicate_tags_in_index_list
{
typedef typename mpl::fold<
IndexList,
mpl::set0<>,
duplicate_tag_list_marker
>::type aux;
BOOST_STATIC_CONSTANT(
bool,value=!(mpl::has_key<aux,duplicate_tag_mark>::value));
};
using no_duplicate_tags=
std::is_same<TagList,mp11::mp_unique<TagList>>;
} /* namespace multi_index::detail */
@@ -0,0 +1,44 @@
/* 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_NO_DUPLICATE_TAGS_IN_INDEX_LIST_HPP
#define BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_IN_INDEX_LIST_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/tag.hpp>
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>
#include <type_traits>
namespace boost{
namespace multi_index{
namespace detail{
/* checks duplication of tags across all indices of a container */
template<typename Index>
using index_tag_list=mp11::mp_rename<
mp11_tag_list<typename Index::tag_list>,mp11::mp_list>;
template<typename IndexList>
using no_duplicate_tags_in_index_list=no_duplicate_tags<
mp11::mp_flatten<mp11::mp_transform<index_tag_list,IndexList>>>;
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -0,0 +1,244 @@
/* 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_NODE_HANDLE_HPP
#define BOOST_MULTI_INDEX_DETAIL_NODE_HANDLE_HPP
#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/addressof.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/multi_index_container_fwd.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_same.hpp>
#include <new>
#include <utility>
namespace boost{
namespace multi_index{
namespace detail{
/* Node handle template class following [container.node] specs.
*/
#include <boost/multi_index/detail/define_if_constexpr_macro.hpp>
template<typename Node,typename Allocator>
class node_handle
{
public:
typedef typename Node::value_type value_type;
typedef Allocator allocator_type;
node_handle()BOOST_NOEXCEPT:node(0){}
node_handle(node_handle&& x)BOOST_NOEXCEPT:node(x.node)
{
if(!x.empty()){
move_construct_allocator(std::move(x));
x.destroy_allocator();
x.node=0;
}
}
~node_handle()
{
if(!empty()){
delete_node();
destroy_allocator();
}
}
node_handle& operator=(node_handle&& x)
{
if(this!=&x){
if(!empty()){
delete_node();
if(!x.empty()){
BOOST_MULTI_INDEX_IF_CONSTEXPR(
allocator_propagate_on_container_move_assignment_t<
allocator_type>::value){
move_assign_allocator(std::move(x));
}
x.destroy_allocator();
}
else{
destroy_allocator();
}
}
else if(!x.empty()){
move_construct_allocator(std::move(x));
x.destroy_allocator();
}
node=x.node;
x.node=0;
}
return *this;
}
value_type& value()const{return node->value();}
allocator_type get_allocator()const{return *allocator_ptr();}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
explicit
#endif
operator bool()const BOOST_NOEXCEPT{return (node!=0);}
#if BOOST_WORKAROUND(BOOST_GCC_VERSION,>=70000)&&__cplusplus<201103L
/* https://github.com/boostorg/config/issues/336 */
#else
BOOST_ATTRIBUTE_NODISCARD
#endif
bool empty()const BOOST_NOEXCEPT{return (node==0);}
void swap(node_handle& x)
BOOST_NOEXCEPT_IF(
allocator_propagate_on_container_swap_t<allocator_type>::value||
allocator_is_always_equal_t<allocator_type>::value)
{
if(!empty()){
if(!x.empty()){
BOOST_MULTI_INDEX_IF_CONSTEXPR(
allocator_propagate_on_container_swap_t<allocator_type>::value){
using std::swap;
swap(*allocator_ptr(),*x.allocator_ptr());
}
}
else{
x.move_construct_allocator(std::move(*this));
destroy_allocator();
}
}
else if(!x.empty()){
move_construct_allocator(std::move(x));
x.destroy_allocator();
}
std::swap(node,x.node);
}
friend void swap(node_handle& x,node_handle& y)
BOOST_NOEXCEPT_IF(noexcept(x.swap(y)))
{
x.swap(y);
}
private:
template <typename,typename,typename>
friend class boost::multi_index::multi_index_container;
node_handle(Node* node_,const allocator_type& al):node(node_)
{
::new (static_cast<void*>(allocator_ptr())) allocator_type(al);
}
void release_node()
{
if(!empty()){
node=0;
destroy_allocator();
}
}
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
const allocator_type* allocator_ptr()const
{
return reinterpret_cast<const allocator_type*>(&space);
}
allocator_type* allocator_ptr()
{
return reinterpret_cast<allocator_type*>(&space);
}
#include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
void move_construct_allocator(node_handle&& x)
{
::new (static_cast<void*>(allocator_ptr()))
allocator_type(std::move(*x.allocator_ptr()));
}
void move_assign_allocator(node_handle&& x)
{
*allocator_ptr()=std::move(*x.allocator_ptr());
}
void destroy_allocator(){allocator_ptr()->~allocator_type();}
void delete_node()
{
typedef allocator_rebind_t<allocator_type,Node> node_allocator;
typedef allocator_pointer_t<node_allocator> node_pointer;
allocator_destroy(*allocator_ptr(),boost::addressof(node->value()));
node_allocator nal(*allocator_ptr());
allocator_deallocate(nal,static_cast<node_pointer>(node),1);
}
Node* node;
typename aligned_storage<
sizeof(allocator_type),
alignment_of<allocator_type>::value
>::type space;
};
#include <boost/multi_index/detail/undef_if_constexpr_macro.hpp>
/* node handle insert return type template class following
* [container.insert.return] specs.
*/
template<typename Iterator,typename NodeHandle>
struct insert_return_type
{
insert_return_type(
Iterator position_,bool inserted_,NodeHandle&& node_):
position(position_),inserted(inserted_),node(std::move(node_)){}
insert_return_type(insert_return_type&& x):
position(x.position),inserted(x.inserted),node(std::move(x.node)){}
insert_return_type& operator=(insert_return_type&& x)
{
position=x.position;
inserted=x.inserted;
node=std::move(x.node);
return *this;
}
Iterator position;
bool inserted;
NodeHandle node;
};
/* utility for SFINAEing merge and related operations */
#define BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(Dst,Src,T) \
typename enable_if_c< \
!is_const< Dst >::value&&!is_const< Src >::value&& \
is_same<typename Dst::node_type,typename Src::node_type>::value, \
T \
>::type
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
+9 -20
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,10 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#include <boost/mpl/bind.hpp>
#include <boost/mpl/reverse_iter_fold.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mp11/algorithm.hpp>
#include <boost/multi_index_container_fwd.hpp>
#include <boost/multi_index/detail/header_holder.hpp>
#include <boost/multi_index/detail/index_node_base.hpp>
@@ -30,31 +27,23 @@ namespace multi_index{
namespace detail{
/* MPL machinery to construct the internal node type associated to an
/* Mp11 machinery to construct the internal node type associated to an
* index list.
*/
struct index_node_applier
{
template<typename IndexSpecifierIterator,typename Super>
struct apply
{
typedef typename mpl::deref<IndexSpecifierIterator>::type index_specifier;
typedef typename index_specifier::
BOOST_NESTED_TEMPLATE node_class<Super>::type type;
};
};
template<typename IndexSpecifier,typename Super>
using node_type=typename IndexSpecifier::template node_class<Super>::type;
template<typename Value,typename IndexSpecifierList,typename Allocator>
struct multi_index_node_type
{
BOOST_STATIC_ASSERT(detail::is_index_list<IndexSpecifierList>::value);
typedef typename mpl::reverse_iter_fold<
IndexSpecifierList,
typedef mp11::mp_reverse_fold<
detail::mp11_index_list<IndexSpecifierList>,
index_node_base<Value,Allocator>,
mpl::bind2<index_node_applier,mpl::_2,mpl::_1>
>::type type;
node_type
> type;
};
} /* namespace multi_index::detail */
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,14 +14,11 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.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{
@@ -40,38 +37,33 @@ namespace detail{
* polymorphism.
*/
template<typename KeyFromValue>
struct index_args_default_compare
{
typedef std::less<typename KeyFromValue::result_type> type;
};
template<typename Arg1,typename Arg2,typename Arg3>
struct ordered_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_compare_type;
typedef typename mpl::eval_if<
mpl::is_na<supplied_compare_type>,
index_args_default_compare<key_from_value_type>,
mpl::identity<supplied_compare_type>
>::type compare_type;
Arg2> supplied_compare_type;
typedef mp11::mp_eval_if_c<
!std::is_void<supplied_compare_type>::value,
supplied_compare_type,
std::less,
typename key_from_value_type::result_type
> compare_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<compare_type>::value);
BOOST_STATIC_ASSERT(!std::is_void<key_from_value_type>::value);
BOOST_STATIC_ASSERT(!std::is_void<compare_type>::value);
};
} /* namespace multi_index::detail */
@@ -80,4 +72,4 @@ struct ordered_index_args
} /* namespace boost */
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -41,13 +41,12 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/core/allocator_access.hpp>
#include <cstddef>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
#include <boost/mpl/and.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/multi_index/detail/uintptr_type.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -67,21 +66,31 @@ enum ordered_index_side{to_left=false,to_right=true};
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_impl; /* fwd decl. */
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_traits
{
typedef allocator_rebind_t<
Allocator,
ordered_index_node_impl<AugmentPolicy,Allocator>
> allocator;
typedef allocator_pointer_t<allocator> pointer;
typedef allocator_const_pointer_t<allocator> const_pointer;
typedef allocator_difference_type_t<allocator> difference_type;
typedef allocator_size_type_t<allocator> size_type;
};
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_std_base
{
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
ordered_index_node_impl<AugmentPolicy,Allocator>
>::type::pointer pointer;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
ordered_index_node_impl<AugmentPolicy,Allocator>
>::type::const_pointer const_pointer;
typedef ordered_index_color& color_ref;
typedef pointer& parent_ref;
typedef ordered_index_node_traits<
AugmentPolicy,Allocator> node_traits;
typedef typename node_traits::allocator node_allocator;
typedef typename node_traits::pointer pointer;
typedef typename node_traits::const_pointer const_pointer;
typedef typename node_traits::difference_type difference_type;
typedef typename node_traits::size_type size_type;
typedef ordered_index_color& color_ref;
typedef pointer& parent_ref;
ordered_index_color& color(){return color_;}
ordered_index_color color()const{return color_;}
@@ -120,14 +129,20 @@ private:
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_compressed_base
{
typedef ordered_index_node_traits<
AugmentPolicy,Allocator> node_traits;
typedef typename node_traits::allocator node_allocator;
typedef ordered_index_node_impl<
AugmentPolicy,Allocator>* pointer;
AugmentPolicy,Allocator>* pointer;
typedef const ordered_index_node_impl<
AugmentPolicy,Allocator>* const_pointer;
AugmentPolicy,Allocator>* const_pointer;
typedef typename node_traits::difference_type difference_type;
typedef typename node_traits::size_type size_type;
struct color_ref
{
color_ref(uintptr_type* r_):r(r_){}
color_ref(const color_ref& x):r(x.r){}
operator ordered_index_color()const
{
@@ -153,6 +168,7 @@ struct ordered_index_node_compressed_base
struct parent_ref
{
parent_ref(uintptr_type* r_):r(r_){}
parent_ref(const parent_ref& x):r(x.r){}
operator pointer()const
{
@@ -211,20 +227,17 @@ struct ordered_index_node_impl_base:
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
AugmentPolicy::template augmented_node<
typename mpl::if_c<
mp11::mp_if_c<
!(has_uintptr_type::value)||
(alignment_of<
ordered_index_node_compressed_base<AugmentPolicy,Allocator>
>::value%2)||
!(is_same<
typename boost::detail::allocator::rebind_to<
Allocator,
ordered_index_node_impl<AugmentPolicy,Allocator>
>::type::pointer,
typename ordered_index_node_traits<AugmentPolicy,Allocator>::pointer,
ordered_index_node_impl<AugmentPolicy,Allocator>*>::value),
ordered_index_node_std_base<AugmentPolicy,Allocator>,
ordered_index_node_compressed_base<AugmentPolicy,Allocator>
>::type
>
>::type
#else
AugmentPolicy::template augmented_node<
@@ -398,7 +411,7 @@ public:
ordered_index_node_impl::rebalance(x,header->parent());
}
static pointer rebalance_for_erase(
static pointer rebalance_for_extract(
pointer z,parent_ref root,pointer& leftmost,pointer& rightmost)
{
pointer y=z;
@@ -566,18 +579,18 @@ template<typename AugmentPolicy,typename Super>
struct ordered_index_node_trampoline:
ordered_index_node_impl<
AugmentPolicy,
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
>
{
typedef ordered_index_node_impl<
AugmentPolicy,
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
> impl_type;
};
@@ -589,11 +602,21 @@ private:
typedef ordered_index_node_trampoline<AugmentPolicy,Super> trampoline;
public:
typedef typename trampoline::impl_type impl_type;
typedef typename trampoline::color_ref impl_color_ref;
typedef typename trampoline::parent_ref impl_parent_ref;
typedef typename trampoline::pointer impl_pointer;
typedef typename trampoline::const_pointer const_impl_pointer;
typedef typename trampoline::impl_type impl_type;
typedef typename trampoline::color_ref impl_color_ref;
typedef typename trampoline::parent_ref impl_parent_ref;
typedef typename trampoline::pointer impl_pointer;
typedef typename trampoline::const_pointer const_impl_pointer;
typedef typename trampoline::difference_type difference_type;
typedef typename trampoline::size_type size_type;
typedef allocator_rebind_t<
typename trampoline::node_allocator,
ordered_index_node> final_allocator_type;
typedef allocator_pointer_t<
final_allocator_type> pointer;
typedef allocator_const_pointer_t<
final_allocator_type> const_pointer;
impl_color_ref color(){return trampoline::color();}
ordered_index_color color()const{return trampoline::color();}
@@ -632,20 +655,24 @@ public:
raw_ptr<const impl_type*>(x)));
}
/* interoperability with bidir_node_iterator */
/* Interoperability with bidir_node_iterator and index impl.
* Templated for raw-pointer/non-raw-pointer versions.
*/
static void increment(ordered_index_node*& x)
template<typename NodePtr>
static void increment(NodePtr& x)
{
impl_pointer xi=x->impl();
trampoline::increment(xi);
x=from_impl(xi);
x=NodePtr(from_impl(xi));
}
static void decrement(ordered_index_node*& x)
template<typename NodePtr>
static void decrement(NodePtr& x)
{
impl_pointer xi=x->impl();
trampoline::decrement(xi);
x=from_impl(xi);
x=NodePtr(from_impl(xi));
}
};
@@ -1,4 +1,4 @@
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
/* 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)
@@ -41,8 +41,9 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/and.hpp>
#include <boost/mp11/function.hpp>
#include <boost/multi_index/detail/promotes_arg.hpp>
#include <type_traits>
#include <utility>
namespace boost{
@@ -70,7 +71,7 @@ inline Node* ordered_index_find(
return ordered_index_find(
top,y,key,x,comp,
mpl::and_<
mp11::mp_and<
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
}
@@ -81,10 +82,10 @@ template<
>
inline Node* ordered_index_find(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
const typename KeyFromValue::result_type& x,
const CompatibleCompare& comp,std::true_type)
{
return ordered_index_find(top,y,key,x,comp,mpl::false_());
return ordered_index_find(top,y,key,x,comp,std::false_type());
}
template<
@@ -93,7 +94,7 @@ template<
>
inline Node* ordered_index_find(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
const CompatibleCompare& comp,std::false_type)
{
Node* y0=y;
@@ -129,10 +130,10 @@ template<
>
inline Node* ordered_index_lower_bound(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
const typename KeyFromValue::result_type& x,
const CompatibleCompare& comp,std::true_type)
{
return ordered_index_lower_bound(top,y,key,x,comp,mpl::false_());
return ordered_index_lower_bound(top,y,key,x,comp,std::false_type());
}
template<
@@ -141,7 +142,7 @@ template<
>
inline Node* ordered_index_lower_bound(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
const CompatibleCompare& comp,std::false_type)
{
while(top){
if(!comp(key(top->value()),x)){
@@ -175,10 +176,10 @@ template<
>
inline Node* ordered_index_upper_bound(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
const typename KeyFromValue::result_type& x,
const CompatibleCompare& comp,std::true_type)
{
return ordered_index_upper_bound(top,y,key,x,comp,mpl::false_());
return ordered_index_upper_bound(top,y,key,x,comp,std::false_type());
}
template<
@@ -187,7 +188,7 @@ template<
>
inline Node* ordered_index_upper_bound(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
const CompatibleCompare& comp,std::false_type)
{
while(top){
if(comp(x,key(top->value()))){
@@ -212,7 +213,7 @@ inline std::pair<Node*,Node*> ordered_index_equal_range(
return ordered_index_equal_range(
top,y,key,x,comp,
mpl::and_<
mp11::mp_and<
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
}
@@ -223,10 +224,10 @@ template<
>
inline std::pair<Node*,Node*> ordered_index_equal_range(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
const typename KeyFromValue::result_type& x,
const CompatibleCompare& comp,std::true_type)
{
return ordered_index_equal_range(top,y,key,x,comp,mpl::false_());
return ordered_index_equal_range(top,y,key,x,comp,std::false_type());
}
template<
@@ -235,7 +236,7 @@ template<
>
inline std::pair<Node*,Node*> ordered_index_equal_range(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
const CompatibleCompare& comp,std::false_type)
{
while(top){
if(comp(key(top->value()),x)){
@@ -248,9 +249,9 @@ inline std::pair<Node*,Node*> ordered_index_equal_range(
else{
return std::pair<Node*,Node*>(
ordered_index_lower_bound(
Node::from_impl(top->left()),top,key,x,comp,mpl::false_()),
Node::from_impl(top->left()),top,key,x,comp,std::false_type()),
ordered_index_upper_bound(
Node::from_impl(top->right()),y,key,x,comp,mpl::false_()));
Node::from_impl(top->right()),y,key,x,comp,std::false_type()));
}
}
@@ -1,4 +1,4 @@
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
/* 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,15 +14,15 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/intrinsics.hpp>
#include <boost/detail/workaround.hpp>
#include <type_traits>
/* Metafunctions to check if f(arg1,arg2) promotes either arg1 to the type of
* arg2 or viceversa. By default, (i.e. if it cannot be determined), no
* promotion is assumed.
*/
#if !defined(BOOST_IS_CONVERTIBLE)
#if BOOST_WORKAROUND(BOOST_MSVC,<1400)
namespace boost{
@@ -31,10 +31,10 @@ namespace multi_index{
namespace detail{
template<typename F,typename Arg1,typename Arg2>
struct promotes_1st_arg:mpl::false_{};
struct promotes_1st_arg:std::false_type{};
template<typename F,typename Arg1,typename Arg2>
struct promotes_2nd_arg:mpl::false_{};
struct promotes_2nd_arg:std::false_type{};
} /* namespace multi_index::detail */
@@ -44,8 +44,7 @@ struct promotes_2nd_arg:mpl::false_{};
#else
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mp11/function.hpp>
#include <boost/multi_index/detail/is_transparent.hpp>
#include <boost/type_traits/is_convertible.hpp>
@@ -57,8 +56,8 @@ namespace detail{
template<typename F,typename Arg1,typename Arg2>
struct promotes_1st_arg:
mpl::and_<
mpl::not_<is_transparent<F,Arg1,Arg2> >,
mp11::mp_and<
mp11::mp_not<is_transparent<F,Arg1,Arg2> >,
is_convertible<const Arg1,Arg2>,
is_transparent<F,Arg2,Arg2>
>
@@ -66,8 +65,8 @@ struct promotes_1st_arg:
template<typename F,typename Arg1,typename Arg2>
struct promotes_2nd_arg:
mpl::and_<
mpl::not_<is_transparent<F,Arg1,Arg2> >,
mp11::mp_and<
mp11::mp_not<is_transparent<F,Arg1,Arg2> >,
is_convertible<const Arg2,Arg1>,
is_transparent<F,Arg1,Arg1>
>
@@ -79,5 +78,5 @@ struct promotes_2nd_arg:
} /* namespace boost */
#endif /* defined(BOOST_IS_CONVERTIBLE) */
#endif
#endif
+5 -6
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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,8 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_same.hpp>
#include <type_traits>
namespace boost{
@@ -26,13 +25,13 @@ namespace detail{
/* gets the underlying pointer of a pointer-like value */
template<typename RawPointer>
inline RawPointer raw_ptr(RawPointer const& p,mpl::true_)
inline RawPointer raw_ptr(RawPointer const& p,std::true_type)
{
return p;
}
template<typename RawPointer,typename Pointer>
inline RawPointer raw_ptr(Pointer const& p,mpl::false_)
inline RawPointer raw_ptr(Pointer const& p,std::false_type)
{
return p==Pointer(0)?0:&*p;
}
@@ -40,7 +39,7 @@ inline RawPointer raw_ptr(Pointer const& p,mpl::false_)
template<typename RawPointer,typename Pointer>
inline RawPointer raw_ptr(Pointer const& p)
{
return raw_ptr<RawPointer>(p,is_same<RawPointer,Pointer>());
return raw_ptr<RawPointer>(p,std::is_same<RawPointer,Pointer>());
}
} /* namespace multi_index::detail */
@@ -0,0 +1,11 @@
/* 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.
*/
#define BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
#undef BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,12 +14,11 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/core/allocator_access.hpp>
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
#include <boost/multi_index/detail/rnd_index_ptr_array.hpp>
#include <boost/noncopyable.hpp>
#include <cstddef>
namespace boost{
@@ -45,10 +44,10 @@ class random_access_index_loader_base:private noncopyable
{
protected:
typedef random_access_index_node_impl<
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
Allocator,
char
>::type
>
> node_impl_type;
typedef typename node_impl_type::pointer node_impl_pointer;
typedef random_access_index_ptr_array<Allocator> ptr_array;
@@ -68,9 +67,9 @@ protected:
node_impl_pointer n=header;
next(n)=n;
for(std::size_t i=ptrs.size();i--;){
for(size_type i=ptrs.size();i--;){
n=prev(n);
std::size_t d=position(n);
size_type d=position(n);
if(d!=i){
node_impl_pointer m=prev(next_at(i));
std::swap(m->up(),n->up());
@@ -94,6 +93,8 @@ protected:
}
private:
typedef allocator_size_type_t<Allocator> size_type;
void preprocess()
{
if(!preprocessed){
@@ -112,17 +113,17 @@ private:
}
}
std::size_t position(node_impl_pointer x)const
size_type position(node_impl_pointer x)const
{
return (std::size_t)(x->up()-ptrs.begin());
return (size_type)(x->up()-ptrs.begin());
}
node_impl_pointer& next_at(std::size_t n)const
node_impl_pointer& next_at(size_type n)const
{
return *ptrs.at(n);
}
node_impl_pointer& prev_at(std::size_t n)const
node_impl_pointer& prev_at(size_type n)const
{
return *(prev_spc.data()+n);
}
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -14,8 +14,8 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/core/allocator_access.hpp>
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <cstddef>
@@ -30,18 +30,16 @@ namespace detail{
template<typename Allocator>
struct random_access_index_node_impl
{
typedef typename
boost::detail::allocator::rebind_to<
typedef allocator_rebind_t<
Allocator,random_access_index_node_impl
>::type::pointer pointer;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,random_access_index_node_impl
>::type::const_pointer const_pointer;
typedef typename
boost::detail::allocator::rebind_to<
> node_allocator;
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;
typedef allocator_rebind_t<
Allocator,pointer
>::type::pointer ptr_pointer;
> ptr_allocator;
typedef allocator_pointer_t<ptr_allocator> ptr_pointer;
ptr_pointer& up(){return up_;}
ptr_pointer up()const{return up_;}
@@ -58,14 +56,14 @@ struct random_access_index_node_impl
x=*(x->up()-1);
}
static void advance(pointer& x,std::ptrdiff_t n)
static void advance(pointer& x,difference_type n)
{
x=*(x->up()+n);
}
static std::ptrdiff_t distance(pointer x,pointer y)
static difference_type distance(pointer x,pointer y)
{
return y->up()-x->up();
return static_cast<difference_type>(y->up()-x->up());
}
/* algorithmic stuff */
@@ -169,6 +167,25 @@ struct random_access_index_node_impl
}
}
static ptr_pointer gather_nulls(
ptr_pointer pbegin,ptr_pointer pend,ptr_pointer x)
{
for(ptr_pointer p=pbegin;p!=x;++p){
if(*p){
*pbegin=*p;
(*pbegin)->up()=pbegin;
++pbegin;
}
}
for(ptr_pointer p=pend;p!=x;){
if(*--p){
*--pend=*p;
(*pend)->up()=pend;
}
}
return pbegin;
}
private:
ptr_pointer up_;
};
@@ -176,17 +193,17 @@ private:
template<typename Super>
struct random_access_index_node_trampoline:
random_access_index_node_impl<
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
>
{
typedef random_access_index_node_impl<
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
> impl_type;
};
@@ -198,10 +215,18 @@ private:
typedef random_access_index_node_trampoline<Super> trampoline;
public:
typedef typename trampoline::impl_type impl_type;
typedef typename trampoline::pointer impl_pointer;
typedef typename trampoline::const_pointer const_impl_pointer;
typedef typename trampoline::ptr_pointer impl_ptr_pointer;
typedef typename trampoline::impl_type impl_type;
typedef typename trampoline::pointer impl_pointer;
typedef typename trampoline::const_pointer const_impl_pointer;
typedef typename trampoline::difference_type difference_type;
typedef typename trampoline::ptr_pointer impl_ptr_pointer;
typedef allocator_rebind_t<
typename trampoline::node_allocator,
random_access_index_node> final_allocator_type;
typedef allocator_pointer_t<
final_allocator_type> pointer;
typedef allocator_const_pointer_t<
final_allocator_type> const_pointer;
impl_ptr_pointer& up(){return trampoline::up();}
impl_ptr_pointer up()const{return trampoline::up();}
@@ -236,28 +261,28 @@ public:
/* interoperability with rnd_node_iterator */
static void increment(random_access_index_node*& x)
static void increment(pointer& x)
{
impl_pointer xi=x->impl();
trampoline::increment(xi);
x=from_impl(xi);
x=pointer(from_impl(xi));
}
static void decrement(random_access_index_node*& x)
static void decrement(pointer& x)
{
impl_pointer xi=x->impl();
trampoline::decrement(xi);
x=from_impl(xi);
x=pointer(from_impl(xi));
}
static void advance(random_access_index_node*& x,std::ptrdiff_t n)
static void advance(pointer& x,difference_type n)
{
impl_pointer xi=x->impl();
trampoline::advance(xi,n);
x=from_impl(xi);
x=pointer(from_impl(xi));
}
static std::ptrdiff_t distance(
static difference_type distance(
random_access_index_node* x,random_access_index_node* y)
{
return trampoline::distance(x->impl(),y->impl());
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -83,7 +83,7 @@ template<typename Node,typename Allocator,typename Compare>
void random_access_index_inplace_merge(
const Allocator& al,
random_access_index_ptr_array<Allocator>& ptrs,
BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp)
typename Node::impl_ptr_pointer first1,Compare comp)
{
typedef typename Node::value_type value_type;
typedef typename Node::impl_pointer impl_pointer;
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,12 +14,11 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/core/allocator_access.hpp>
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
#include <boost/multi_index/detail/rnd_index_node.hpp>
#include <boost/noncopyable.hpp>
#include <cstddef>
namespace boost{
@@ -33,20 +32,24 @@ template<typename Allocator>
class random_access_index_ptr_array:private noncopyable
{
typedef random_access_index_node_impl<
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
Allocator,
char
>::type
> node_impl_type;
>
> node_impl_type;
public:
typedef typename node_impl_type::pointer value_type;
typedef typename boost::detail::allocator::rebind_to<
typedef typename node_impl_type::pointer value_type;
typedef allocator_rebind_t<
Allocator,value_type
>::type::pointer pointer;
> value_allocator;
typedef allocator_pointer_t<
value_allocator> pointer;
typedef allocator_size_type_t<
value_allocator> size_type;
random_access_index_ptr_array(
const Allocator& al,value_type end_,std::size_t sz):
const Allocator& al,value_type end_,size_type sz):
size_(sz),
capacity_(sz),
spc(al,capacity_+1)
@@ -55,8 +58,8 @@ public:
end_->up()=end();
}
std::size_t size()const{return size_;}
std::size_t capacity()const{return capacity_;}
size_type size()const{return size_;}
size_type capacity()const{return capacity_;}
void room_for_one()
{
@@ -65,7 +68,7 @@ public:
}
}
void reserve(std::size_t c)
void reserve(size_type c)
{
if(c>capacity_)set_capacity(c);
}
@@ -77,7 +80,7 @@ public:
pointer begin()const{return ptrs();}
pointer end()const{return ptrs()+size_;}
pointer at(std::size_t n)const{return ptrs()+n;}
pointer at(size_type n)const{return ptrs()+n;}
void push_back(value_type x)
{
@@ -108,9 +111,17 @@ public:
spc.swap(x.spc);
}
template<typename BoolConstant>
void swap(random_access_index_ptr_array& x,BoolConstant swap_allocators)
{
std::swap(size_,x.size_);
std::swap(capacity_,x.capacity_);
spc.swap(x.spc,swap_allocators);
}
private:
std::size_t size_;
std::size_t capacity_;
size_type size_;
size_type capacity_;
auto_space<value_type,Allocator> spc;
pointer ptrs()const
@@ -118,7 +129,7 @@ private:
return spc.data();
}
void set_capacity(std::size_t c)
void set_capacity(size_type c)
{
auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1);
node_impl_type::transfer(begin(),end()+1,spc1.data());
@@ -1,4 +1,4 @@
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
/* 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)
@@ -14,11 +14,11 @@
#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/serialization/nvp.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/core/serialization.hpp>
#endif
namespace boost{
@@ -34,7 +34,7 @@ class rnd_node_iterator:
public random_access_iterator_helper<
rnd_node_iterator<Node>,
typename Node::value_type,
std::ptrdiff_t,
typename Node::difference_type,
const typename Node::value_type*,
const typename Node::value_type&>
{
@@ -60,13 +60,13 @@ public:
return *this;
}
rnd_node_iterator& operator+=(std::ptrdiff_t n)
rnd_node_iterator& operator+=(typename Node::difference_type n)
{
Node::advance(node,n);
return *this;
}
rnd_node_iterator& operator-=(std::ptrdiff_t n)
rnd_node_iterator& operator-=(typename Node::difference_type n)
{
Node::advance(node,-n);
return *this;
@@ -77,23 +77,27 @@ public:
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
*/
BOOST_SERIALIZATION_SPLIT_MEMBER()
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=node;
ar<<serialization::make_nvp("pointer",bnode);
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>>serialization::make_nvp("pointer",bnode);
node=static_cast<Node*>(bnode);
ar>>core::make_nvp("pointer",bnode);
node=typename Node::pointer(static_cast<Node*>(bnode));
}
#endif
@@ -101,10 +105,10 @@ public:
typedef Node node_type;
Node* get_node()const{return node;}
Node* get_node()const{return raw_ptr<Node*>(node);}
private:
Node* node;
typename Node::pointer node;
};
template<typename Node>
@@ -124,7 +128,7 @@ bool operator<(
}
template<typename Node>
std::ptrdiff_t operator-(
typename Node::difference_type operator-(
const rnd_node_iterator<Node>& x,
const rnd_node_iterator<Node>& y)
{
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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,9 +14,10 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/and.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/mp11/function.hpp>
#include <boost/multi_index/detail/promotes_arg.hpp>
#include <cstddef>
#include <type_traits>
#include <utility>
namespace boost{
@@ -30,19 +31,30 @@ namespace detail{
*/
template<typename Pointer>
inline std::size_t ranked_node_size(Pointer x)
struct ranked_node_size_type
{
typedef typename boost::pointer_traits<Pointer>::
element_type::size_type type;
};
template<typename Pointer>
inline typename ranked_node_size_type<Pointer>::type
ranked_node_size(Pointer x)
{
return x!=Pointer(0)?x->size:0;
}
template<typename Pointer>
inline Pointer ranked_index_nth(std::size_t n,Pointer end_)
inline Pointer ranked_index_nth(
typename ranked_node_size_type<Pointer>::type n,Pointer end_)
{
typedef typename ranked_node_size_type<Pointer>::type size_type;
Pointer top=end_->parent();
if(top==Pointer(0)||n>=top->size)return end_;
for(;;){
std::size_t s=ranked_node_size(top->left());
size_type s=ranked_node_size(top->left());
if(n==s)return top;
if(n<s)top=top->left();
else{
@@ -53,13 +65,16 @@ inline Pointer ranked_index_nth(std::size_t n,Pointer end_)
}
template<typename Pointer>
inline std::size_t ranked_index_rank(Pointer x,Pointer end_)
inline typename ranked_node_size_type<Pointer>::type
ranked_index_rank(Pointer x,Pointer end_)
{
typedef typename ranked_node_size_type<Pointer>::type size_type;
Pointer top=end_->parent();
if(top==Pointer(0))return 0;
if(x==end_)return top->size;
std::size_t s=ranked_node_size(x->left());
size_type s=ranked_node_size(x->left());
while(x!=top){
Pointer z=x->parent();
if(x==z->right()){
@@ -74,7 +89,7 @@ template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_find_rank(
inline typename Node::size_type ranked_index_find_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp)
{
@@ -82,7 +97,7 @@ inline std::size_t ranked_index_find_rank(
return ranked_index_find_rank(
top,y,key,x,comp,
mpl::and_<
mp11::mp_and<
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
}
@@ -91,27 +106,29 @@ template<
typename Node,typename KeyFromValue,
typename CompatibleCompare
>
inline std::size_t ranked_index_find_rank(
inline typename Node::size_type ranked_index_find_rank(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
const typename KeyFromValue::result_type& x,
const CompatibleCompare& comp,std::true_type)
{
return ranked_index_find_rank(top,y,key,x,comp,mpl::false_());
return ranked_index_find_rank(top,y,key,x,comp,std::false_type());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_find_rank(
inline typename Node::size_type ranked_index_find_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
const CompatibleCompare& comp,std::false_type)
{
typedef typename Node::size_type size_type;
if(!top)return 0;
std::size_t s=top->size,
s0=s;
Node* y0=y;
size_type s=top->impl()->size,
s0=s;
Node* y0=y;
do{
if(!comp(key(top->value()),x)){
@@ -129,7 +146,7 @@ template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_lower_bound_rank(
inline typename Node::size_type ranked_index_lower_bound_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp)
{
@@ -144,25 +161,27 @@ template<
typename Node,typename KeyFromValue,
typename CompatibleCompare
>
inline std::size_t ranked_index_lower_bound_rank(
inline typename Node::size_type ranked_index_lower_bound_rank(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
const typename KeyFromValue::result_type& x,
const CompatibleCompare& comp,std::true_type)
{
return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_());
return ranked_index_lower_bound_rank(top,y,key,x,comp,std::false_type());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_lower_bound_rank(
inline typename Node::size_type ranked_index_lower_bound_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
const CompatibleCompare& comp,std::false_type)
{
typedef typename Node::size_type size_type;
if(!top)return 0;
std::size_t s=top->size;
size_type s=top->impl()->size;
do{
if(!comp(key(top->value()),x)){
@@ -180,7 +199,7 @@ template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_upper_bound_rank(
inline typename Node::size_type ranked_index_upper_bound_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp)
{
@@ -195,25 +214,27 @@ template<
typename Node,typename KeyFromValue,
typename CompatibleCompare
>
inline std::size_t ranked_index_upper_bound_rank(
inline typename Node::size_type ranked_index_upper_bound_rank(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
const typename KeyFromValue::result_type& x,
const CompatibleCompare& comp,std::true_type)
{
return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_());
return ranked_index_upper_bound_rank(top,y,key,x,comp,std::false_type());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_upper_bound_rank(
inline typename Node::size_type ranked_index_upper_bound_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
const CompatibleCompare& comp,std::false_type)
{
typedef typename Node::size_type size_type;
if(!top)return 0;
std::size_t s=top->size;
size_type s=top->impl()->size;
do{
if(comp(x,key(top->value()))){
@@ -231,7 +252,8 @@ template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
inline std::pair<typename Node::size_type,typename Node::size_type>
ranked_index_equal_range_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp)
{
@@ -239,7 +261,7 @@ inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
return ranked_index_equal_range_rank(
top,y,key,x,comp,
mpl::and_<
mp11::mp_and<
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
}
@@ -248,25 +270,29 @@ template<
typename Node,typename KeyFromValue,
typename CompatibleCompare
>
inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
inline std::pair<typename Node::size_type,typename Node::size_type>
ranked_index_equal_range_rank(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
const typename KeyFromValue::result_type& x,
const CompatibleCompare& comp,std::true_type)
{
return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_());
return ranked_index_equal_range_rank(top,y,key,x,comp,std::false_type());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
inline std::pair<typename Node::size_type,typename Node::size_type>
ranked_index_equal_range_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
const CompatibleCompare& comp,std::false_type)
{
if(!top)return std::pair<std::size_t,std::size_t>(0,0);
typedef typename Node::size_type size_type;
std::size_t s=top->size;
if(!top)return std::pair<size_type,size_type>((size_type)0,(size_type)0);
size_type s=top->impl()->size;
do{
if(comp(key(top->value()),x)){
@@ -278,17 +304,17 @@ inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
top=Node::from_impl(top->left());
}
else{
return std::pair<std::size_t,std::size_t>(
s-top->size+
return std::pair<size_type,size_type>(
(size_type)(s-top->impl()->size+
ranked_index_lower_bound_rank(
Node::from_impl(top->left()),top,key,x,comp,mpl::false_()),
s-ranked_node_size(top->right())+
Node::from_impl(top->left()),top,key,x,comp,std::false_type())),
(size_type)(s-ranked_node_size(top->right())+
ranked_index_upper_bound_rank(
Node::from_impl(top->right()),y,key,x,comp,mpl::false_()));
Node::from_impl(top->right()),y,key,x,comp,std::false_type())));
}
}while(top);
return std::pair<std::size_t,std::size_t>(s,s);
return std::pair<size_type,size_type>(s,s);
}
} /* namespace multi_index::detail */
+214 -91
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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)
@@ -15,9 +15,9 @@
/* Safe mode machinery, in the spirit of Cay Hortmann's "Safe STL"
* (http://www.horstmann.com/safestl.html).
* In this mode, containers of type Container are derived from
* safe_container<Container>, and their corresponding iterators
* are wrapped with safe_iterator. These classes provide
* In this mode, containers have to redefine their iterators as
* safe_iterator<base_iterator> and keep a tracking object member of
* type safe_container<safe_iterator<base_iterator> >. These classes provide
* an internal record of which iterators are at a given moment associated
* to a given container, and properly mark the iterators as invalid
* when the container gets destroyed.
@@ -80,6 +80,11 @@
safe_mode::check_is_owner(it,cont), \
safe_mode::not_owner);
#define BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,cont) \
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \
safe_mode::check_belongs_in_some_index(it,cont), \
safe_mode::not_owner);
#define BOOST_MULTI_INDEX_CHECK_SAME_OWNER(it0,it1) \
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \
safe_mode::check_same_owner(it0,it1), \
@@ -105,22 +110,28 @@
safe_mode::check_different_container(cont0,cont1), \
safe_mode::same_container);
#define BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(cont0,cont1) \
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \
safe_mode::check_equal_allocators(cont0,cont1), \
safe_mode::unequal_allocators);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/detail/iterator.hpp>
#include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/multi_index/detail/any_container_view.hpp>
#include <boost/multi_index/detail/iter_adaptor.hpp>
#include <boost/multi_index/safe_mode_errors.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/is_same.hpp>
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/version.hpp>
#include <boost/core/serialization.hpp>
#endif
#if defined(BOOST_HAS_THREADS)
#include <boost/detail/lightweight_mutex.hpp>
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#include <boost/multi_index/detail/scoped_bilock.hpp>
#endif
namespace boost{
@@ -158,18 +169,29 @@ inline bool check_decrementable_iterator(const Iterator& it)
return (it.valid()&&it!=it.owner()->begin())||it.unchecked();
}
template<typename Iterator>
template<typename Iterator,typename Container>
inline bool check_is_owner(
const Iterator& it,const typename Iterator::container_type& cont)
const Iterator& it,const Container& cont)
{
return (it.valid()&&it.owner()==&cont)||it.unchecked();
return (it.valid()&&
it.owner()->container()==cont.end().owner()->container())
||it.unchecked();
}
template<typename Iterator,typename MultiIndexContainer>
inline bool check_belongs_in_some_index(
const Iterator& it,const MultiIndexContainer& cont)
{
return (it.valid()&&it.owner()->end().get_node()==cont.end().get_node())
||it.unchecked();
}
template<typename Iterator>
inline bool check_same_owner(const Iterator& it0,const Iterator& it1)
{
return (it0.valid()&&it1.valid()&&it0.owner()==it1.owner())||
it0.unchecked()||it1.unchecked();
return (it0.valid()&&it1.valid()&&
it0.owner()->container()==it1.owner()->container())
||it0.unchecked()||it1.unchecked();
}
template<typename Iterator>
@@ -213,6 +235,28 @@ inline bool check_outside_range(
return true;
}
template<typename Iterator1,typename Iterator2>
inline bool check_outside_range(
const Iterator1& it,const Iterator2& it0,const Iterator2& it1)
{
if(it.valid()&&it!=it.owner()->end()&&it0.valid()){
Iterator2 last=it0.owner()->end();
bool found=false;
Iterator2 first=it0;
for(;first!=last;++first){
if(first==it1)break;
/* crucial that this check goes after previous break */
if(boost::addressof(*first)==boost::addressof(*it))found=true;
}
if(first!=it1)return false;
return !found;
}
return true;
}
template<typename Iterator,typename Difference>
inline bool check_in_bounds(const Iterator& it,Difference n)
{
@@ -229,42 +273,33 @@ inline bool check_different_container(
return &cont0!=&cont1;
}
/* Invalidates all iterators equivalent to that given. Safe containers
* must call this when deleting elements: the safe mode framework cannot
* perform this operation automatically without outside help.
*/
template<typename Iterator>
inline void detach_equivalent_iterators(Iterator& it)
template<typename Container1,typename Container2>
inline bool check_different_container(const Container1&,const Container2&)
{
if(it.valid()){
{
#if defined(BOOST_HAS_THREADS)
boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex);
#endif
Iterator *prev_,*next_;
for(
prev_=static_cast<Iterator*>(&it.cont->header);
(next_=static_cast<Iterator*>(prev_->next))!=0;){
if(next_!=&it&&*next_==it){
prev_->next=next_->next;
next_->cont=0;
}
else prev_=next_;
}
}
it.detach();
}
return true;
}
template<typename Container> class safe_container; /* fwd decl. */
template<typename Container0,typename Container1>
inline bool check_equal_allocators(
const Container0& cont0,const Container1& cont1)
{
return cont0.get_allocator()==cont1.get_allocator();
}
} /* namespace multi_index::safe_mode */
/* fwd decls */
namespace detail{
template<typename Container> class safe_container;
template<typename Iterator> void detach_equivalent_iterators(Iterator&);
class safe_container_base; /* fwd decl. */
namespace safe_mode_detail{
/* fwd decls */
class safe_container_base;
template<typename Dst,typename Iterator>
void transfer_equivalent_iterators(Dst&,Iterator,boost::true_type);
template<typename Dst,typename Iterator>
inline void transfer_equivalent_iterators(Dst&,Iterator&,boost::false_type);
class safe_iterator_base
{
@@ -313,14 +348,15 @@ protected:
const safe_container_base* owner()const{return cont;}
BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS:
private:
friend class safe_container_base;
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<typename> friend class safe_mode::safe_container;
template<typename Iterator> friend
void safe_mode::detach_equivalent_iterators(Iterator&);
#endif
template<typename>
friend class safe_mode::safe_container;
template<typename Iterator>
friend void safe_mode::detach_equivalent_iterators(Iterator&);
template<typename Dst,typename Iterator>
friend void safe_mode_detail::transfer_equivalent_iterators(
Dst&,Iterator,boost::true_type);
inline void attach(safe_container_base* cont_);
@@ -334,13 +370,13 @@ class safe_container_base:private noncopyable
public:
safe_container_base(){}
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
protected:
friend class safe_iterator_base;
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<typename Iterator> friend
void safe_mode::detach_equivalent_iterators(Iterator&);
#endif
template<typename Iterator>
friend void safe_mode::detach_equivalent_iterators(Iterator&);
template<typename Dst,typename Iterator>
friend void safe_mode_detail::transfer_equivalent_iterators(
Dst&,Iterator,boost::true_type);
~safe_container_base()
{
@@ -394,42 +430,38 @@ void safe_iterator_base::detach()
}
}
} /* namespace multi_index::detail */
namespace safe_mode{
} /* namespace multi_index::safe_mode::safe_mode_detail */
/* In order to enable safe mode on a container:
* - The container must derive from safe_container<container_type>,
* - The container must keep a member of type safe_container<iterator>,
* - iterators must be generated via safe_iterator, which adapts a
* preexistent unsafe iterator class.
* preexistent unsafe iterator class. safe_iterators are passed the
* address of the previous safe_container member at construction time.
*/
template<typename Container>
class safe_container;
template<typename Iterator,typename Container>
template<typename Iterator>
class safe_iterator:
public detail::iter_adaptor<safe_iterator<Iterator,Container>,Iterator>,
public detail::safe_iterator_base
public detail::iter_adaptor<safe_iterator<Iterator>,Iterator>,
public safe_mode_detail::safe_iterator_base
{
typedef detail::iter_adaptor<safe_iterator,Iterator> super;
typedef detail::safe_iterator_base safe_super;
typedef safe_mode_detail::safe_iterator_base safe_super;
public:
typedef Container container_type;
typedef typename Iterator::reference reference;
typedef typename Iterator::difference_type difference_type;
safe_iterator(){}
explicit safe_iterator(safe_container<container_type>* cont_):
explicit safe_iterator(safe_container<safe_iterator>* cont_):
safe_super(cont_){}
template<typename T0>
safe_iterator(const T0& t0,safe_container<container_type>* cont_):
safe_iterator(const T0& t0,safe_container<safe_iterator>* cont_):
super(Iterator(t0)),safe_super(cont_){}
template<typename T0,typename T1>
safe_iterator(
const T0& t0,const T1& t1,safe_container<container_type>* cont_):
const T0& t0,const T1& t1,safe_container<safe_iterator>* cont_):
super(Iterator(t0,t1)),safe_super(cont_){}
safe_iterator(const safe_iterator& x):super(x),safe_super(x){}
safe_iterator& operator=(const safe_iterator& x)
{
@@ -439,12 +471,11 @@ public:
return *this;
}
const container_type* owner()const
const safe_container<safe_iterator>* owner()const
{
return
static_cast<const container_type*>(
static_cast<const safe_container<container_type>*>(
this->safe_super::owner()));
static_cast<const safe_container<safe_iterator>*>(
this->safe_super::owner());
}
/* get_node is not to be used by the user */
@@ -517,7 +548,11 @@ private:
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
template<class Archive>
void serialize(Archive& ar,const unsigned int version)
{
core::split_member(ar,*this,version);
}
template<class Archive>
void save(Archive& ar,const unsigned int version)const
@@ -535,21 +570,28 @@ private:
#endif
};
template<typename Container>
class safe_container:public detail::safe_container_base
template<typename Iterator>
class safe_container:public safe_mode_detail::safe_container_base
{
typedef detail::safe_container_base super;
typedef safe_mode_detail::safe_container_base super;
detail::any_container_view<Iterator> view;
public:
template<typename Container>
safe_container(const Container& c):view(c){}
const void* container()const{return view.container();}
Iterator begin()const{return view.begin();}
Iterator end()const{return view.end();}
void detach_dereferenceable_iterators()
{
typedef typename Container::iterator iterator;
iterator end_=static_cast<Container*>(this)->end();
iterator *prev_,*next_;
Iterator end_=view.end();
Iterator *prev_,*next_;
for(
prev_=static_cast<iterator*>(&this->header);
(next_=static_cast<iterator*>(prev_->next))!=0;){
prev_=static_cast<Iterator*>(&this->header);
(next_=static_cast<Iterator*>(prev_->next))!=0;){
if(*next_!=end_){
prev_->next=next_->next;
next_->cont=0;
@@ -558,21 +600,102 @@ public:
}
}
void swap(safe_container<Container>& x)
void swap(safe_container<Iterator>& x)
{
super::swap(x);
}
};
/* Invalidates all iterators equivalent to that given. Safe containers
* must call this when deleting elements: the safe mode framework cannot
* perform this operation automatically without outside help.
*/
template<typename Iterator>
inline void detach_equivalent_iterators(Iterator& it)
{
if(it.valid()){
{
#if defined(BOOST_HAS_THREADS)
boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex);
#endif
Iterator *prev_,*next_;
for(
prev_=static_cast<Iterator*>(&it.cont->header);
(next_=static_cast<Iterator*>(prev_->next))!=0;){
if(next_!=&it&&*next_==it){
prev_->next=next_->next;
next_->cont=0;
}
else prev_=next_;
}
}
it.detach();
}
}
/* Transfers iterators equivalent to that given to Dst, if that container has
* the same iterator type; otherwise, detaches them.
*/
template<typename Dst,typename Iterator>
inline void transfer_equivalent_iterators(Dst& dst,Iterator& i)
{
safe_mode_detail::transfer_equivalent_iterators(
dst,i,boost::is_same<Iterator,typename Dst::iterator>());
}
namespace safe_mode_detail{
template<typename Dst,typename Iterator>
inline void transfer_equivalent_iterators(
Dst& dst,Iterator it,boost::true_type /* same iterator type */)
{
if(it.valid()){
{
safe_container_base* cont_=dst.end().cont;
#if defined(BOOST_HAS_THREADS)
detail::scoped_bilock<boost::detail::lightweight_mutex>
scoped_bilock(it.cont->mutex,cont_->mutex);
#endif
Iterator *prev_,*next_;
for(
prev_=static_cast<Iterator*>(&it.cont->header);
(next_=static_cast<Iterator*>(prev_->next))!=0;){
if(next_!=&it&&*next_==it){
prev_->next=next_->next;
next_->cont=cont_;
next_->next=cont_->header.next;
cont_->header.next=next_;
}
else prev_=next_;
}
}
/* nothing to do with it, was passed by value and will die now */
}
}
template<typename Dst,typename Iterator>
inline void transfer_equivalent_iterators(
Dst&,Iterator& it,boost::false_type /* same iterator type */)
{
detach_equivalent_iterators(it);
}
} /* namespace multi_index::safe_mode::safe_mode_detail */
} /* namespace multi_index::safe_mode */
} /* namespace multi_index */
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
namespace serialization{
template<typename Iterator,typename Container>
template<typename Iterator>
struct version<
boost::multi_index::safe_mode::safe_iterator<Iterator,Container>
boost::multi_index::safe_mode::safe_iterator<Iterator>
>
{
BOOST_STATIC_CONSTANT(
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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)
@@ -13,8 +13,8 @@
#pragma once
#endif
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/mpl/if.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/mp11/utility.hpp>
namespace boost{
@@ -120,7 +120,7 @@ struct null_guard : public scope_guard_impl_base
template< bool cond, class T >
struct null_guard_return
{
typedef typename boost::mpl::if_c<cond,T,null_guard>::type type;
typedef mp11::mp_if_c<cond,T,null_guard> type;
};
template<typename F>
@@ -0,0 +1,70 @@
/* 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.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_SCOPED_BILOCK_HPP
#define BOOST_MULTI_INDEX_DETAIL_SCOPED_BILOCK_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/core/noncopyable.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <functional>
#include <new>
namespace boost{
namespace multi_index{
namespace detail{
/* Locks/unlocks two RAII-lockable mutexes taking care that locking is done in
* a deadlock-avoiding global order and no double locking happens when the two
* mutexes are the same.
*/
template<typename Mutex>
class scoped_bilock:private noncopyable
{
public:
scoped_bilock(Mutex& mutex1,Mutex& mutex2):mutex_eq(&mutex1==&mutex2)
{
bool mutex_lt=std::less<Mutex*>()(&mutex1,&mutex2);
::new (static_cast<void*>(&lock1)) scoped_lock(mutex_lt?mutex1:mutex2);
if(!mutex_eq)
::new (static_cast<void*>(&lock2)) scoped_lock(mutex_lt?mutex2:mutex1);
}
~scoped_bilock()
{
reinterpret_cast<scoped_lock*>(&lock1)->~scoped_lock();
if(!mutex_eq)
reinterpret_cast<scoped_lock*>(&lock2)->~scoped_lock();
}
private:
typedef typename Mutex::scoped_lock scoped_lock;
typedef typename aligned_storage<
sizeof(scoped_lock),
alignment_of<scoped_lock>::value
>::type scoped_lock_space;
bool mutex_eq;
scoped_lock_space lock1,lock2;
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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)
@@ -14,8 +14,8 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/core/allocator_access.hpp>
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
namespace boost{
@@ -29,14 +29,14 @@ namespace detail{
template<typename Allocator>
struct sequenced_index_node_impl
{
typedef typename
boost::detail::allocator::rebind_to<
typedef allocator_rebind_t<
Allocator,sequenced_index_node_impl
>::type::pointer pointer;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,sequenced_index_node_impl
>::type::const_pointer const_pointer;
> node_allocator;
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;
pointer& prior(){return prior_;}
pointer prior()const{return prior_;}
@@ -55,7 +55,7 @@ struct sequenced_index_node_impl
x->prior()=header->prior();
x->next()=header;
x->prior()->next()=x->next()->prior()=x;
};
}
static void unlink(pointer x)
{
@@ -133,17 +133,17 @@ private:
template<typename Super>
struct sequenced_index_node_trampoline:
sequenced_index_node_impl<
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
>
{
typedef sequenced_index_node_impl<
typename boost::detail::allocator::rebind_to<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
> impl_type;
};
@@ -154,9 +154,17 @@ private:
typedef sequenced_index_node_trampoline<Super> trampoline;
public:
typedef typename trampoline::impl_type impl_type;
typedef typename trampoline::pointer impl_pointer;
typedef typename trampoline::const_pointer const_impl_pointer;
typedef typename trampoline::impl_type impl_type;
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::node_allocator,
sequenced_index_node> final_allocator_type;
typedef allocator_pointer_t<
final_allocator_type> pointer;
typedef allocator_const_pointer_t<
final_allocator_type> const_pointer;
impl_pointer& prior(){return trampoline::prior();}
impl_pointer prior()const{return trampoline::prior();}
@@ -191,20 +199,24 @@ public:
raw_ptr<const impl_type*>(x)));
}
/* interoperability with bidir_node_iterator */
/* Interoperability with bidir_node_iterator and index impl.
* Templated for raw-pointer/non-raw-pointer versions.
*/
static void increment(sequenced_index_node*& x)
template<typename NodePtr>
static void increment(NodePtr& x)
{
impl_pointer xi=x->impl();
trampoline::increment(xi);
x=from_impl(xi);
x=NodePtr(from_impl(xi));
}
static void decrement(sequenced_index_node*& x)
template<typename NodePtr>
static void decrement(NodePtr& x)
{
impl_pointer xi=x->impl();
trampoline::decrement(xi);
x=from_impl(xi);
x=NodePtr(from_impl(xi));
}
};
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* 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,7 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/multi_index/detail/seq_index_node.hpp>
#include <boost/limits.hpp>
#include <boost/type_traits/aligned_storage.hpp>
@@ -77,8 +77,8 @@ void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp)
template<typename Node,typename Compare>
void sequenced_index_collate(
BOOST_DEDUCED_TYPENAME Node::impl_type* x,
BOOST_DEDUCED_TYPENAME Node::impl_type* y,
typename Node::impl_type* x,
typename Node::impl_type* y,
Compare comp)
{
typedef typename Node::impl_type impl_type;
@@ -110,6 +110,8 @@ BOOST_STATIC_CONSTANT(
sequenced_index_sort_max_fill=
(std::size_t)std::numeric_limits<std::size_t>::digits+1);
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
template<typename Node,typename Compare>
void sequenced_index_sort(Node* header,Compare comp)
{
@@ -190,6 +192,8 @@ void sequenced_index_sort(Node* header,Compare comp)
BOOST_CATCH_END
}
#include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
} /* namespace multi_index::detail */
} /* namespace multi_index */
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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)
@@ -14,8 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/version.hpp>
#include <boost/core/serialization.hpp>
namespace boost{
@@ -42,7 +41,11 @@ struct serialization_version
private:
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
template<class Archive>
void serialize(Archive& ar,const unsigned int version)
{
core::split_member(ar,*this,version);
}
template<class Archive>
void save(Archive&,const unsigned int)const{}
@@ -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_TYPE_LIST_HPP
#define BOOST_MULTI_INDEX_DETAIL_TYPE_LIST_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#if defined(BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT)
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
<boost/mpl/push_front.hpp>
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
<boost/mpl/vector.hpp>
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
namespace boost{
namespace multi_index{
namespace detail{
using empty_type_list=mpl::vector0<>;
template<typename TypeList,typename T>
using type_list_push_front=typename mpl::push_front<TypeList,T>::type;
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#else
#include <boost/mp11/list.hpp>
namespace boost{
namespace multi_index{
namespace detail{
using empty_type_list=mp11::mp_list<>;
template<typename TypeList,typename T>
using type_list_push_front=mp11::mp_push_front<TypeList,T>;
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,7 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/bool.hpp>
#include <boost/mp11/integral.hpp>
namespace boost{
@@ -64,8 +64,8 @@ struct uintptr_aux
typedef uintptr_candidates<index>::type type;
};
typedef mpl::bool_<uintptr_aux::has_uintptr_type> has_uintptr_type;
typedef uintptr_aux::type uintptr_type;
typedef mp11::mp_bool<uintptr_aux::has_uintptr_type> has_uintptr_type;
typedef uintptr_aux::type uintptr_type;
} /* namespace multi_index::detail */
@@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* 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,7 +14,6 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
namespace boost{

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