Compare commits

...

69 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
145 changed files with 6495 additions and 4962 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' },
),
]
-47
View File
@@ -1,47 +0,0 @@
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE.txt)
#
# Copyright Rene Rivera 2020.
# For Drone CI we use the Starlark scripting language to reduce duplication.
# As the yaml syntax for Drone CI is rather limited.
#
#
globalenv={}
linuxglobalimage="cppalliance/droneubuntu1404:1"
windowsglobalimage="cppalliance/dronevs2019"
def main(ctx):
return [
linux_cxx("TOOLSET=gcc COMPILER=g++ CXXSTD=03,11 Job 0", "g++", packages="", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x Job 1", "g++", packages="g++-4.4", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.4', 'CXXSTD': '98,0x', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x Job 2", "g++", packages="g++-4.6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.6', 'CXXSTD': '03,0x', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11 Job 3", "g++-4.7", packages="g++-4.7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.7', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11 Job 4", "g++-4.8", packages="g++-4.8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.8', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11 Job 5", "g++-4.9", packages="g++-4.9", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.9', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z Job 6", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z Job 7", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 Job 8", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '03,11,14,17', 'DRONE_JOB_UUID': 'fe5dbbcea5'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17 Job 9", "g++-8", packages="g++-8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '03,11,14,17,2a', 'DRONE_JOB_UUID': '0ade7c2cf9'}, globalenv=globalenv),
linux_cxx("UBSAN=1 TOOLSET=gcc COMPILER=g++-7 CXXSTD=03, Job 10", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'UBSAN': '1', 'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '03,11,14,17', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'LINKFLAGS': '-fuse-ld=gold', 'DRONE_JOB_UUID': 'b1d5781111'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=03,11 Job 11", "clang++", packages="", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '17ba079149'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=/usr/bin/clang++ CXXST Job 12", "/usr/bin/clang++", packages="clang-3.3", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': '/usr/bin/clang++', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '7b52009b64'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=/usr/bin/clang++ CXXST Job 13", "/usr/bin/clang++", packages="clang-3.4", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': '/usr/bin/clang++', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': 'bd307a3ec3'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03, Job 14", "clang++", packages="clang-3.5 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.5', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'fa35e19212'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03, Job 15", "clang++", packages="clang-3.6", llvm_os="precise", llvm_ver="3.6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.6', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'f1abd67035'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03, Job 16", "clang++", packages="clang-3.7", llvm_os="precise", llvm_ver="3.7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.7', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '1574bddb75'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03, Job 17", "clang++-3.8", packages="clang-3.8 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.8', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '0716d9708d'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03, Job 18", "clang++-3.9", packages="clang-3.9 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.9", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.9', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '9e6a55b6b4'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03, Job 19", "clang++-4.0", packages="clang-4.0", llvm_os="trusty", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'b3f0c7f6bb'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03, Job 20", "clang++-5.0", packages="clang-5.0", llvm_os="trusty", llvm_ver="5.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '91032ad7bb'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03, Job 21", "clang++-6.0", packages="clang-6.0", llvm_os="trusty", llvm_ver="6.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '03,11,14,17,2a', 'DRONE_JOB_UUID': '472b07b9fc'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11 Job 22", "clang++-7", packages="clang-7", llvm_os="trusty", llvm_ver="7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '03,11,14,17,2a', 'DRONE_JOB_UUID': '12c6fc06c9'}, globalenv=globalenv),
linux_cxx("UBSAN=1 TOOLSET=clang COMPILER=clang++-7 CXXS Job 23", "clang++-7", packages="clang-7 libstdc++-5-dev", llvm_os="trusty", llvm_ver="7", buildtype="boost", image=linuxglobalimage, environment={'UBSAN': '1', 'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '03,11,14,17,2a', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'DRONE_JOB_UUID': 'd435a6cdd7'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-libc++ CXXSTD= Job 24", "clang++-libc++", packages="libc++-dev", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-libc++', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '4d134bc072'}, globalenv=globalenv),
linux_cxx("UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ Job 25", "clang++-libc++", packages="libc++-dev", buildtype="boost", image=linuxglobalimage, environment={'UBSAN': '1', 'TOOLSET': 'clang', 'COMPILER': 'clang++-libc++', 'CXXSTD': '03,11,14,1z', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'DRONE_JOB_UUID': 'f6e1126ced'}, globalenv=globalenv),
osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,1 Job 26", "clang++", packages="", buildtype="boost", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_OS_NAME': 'osx', 'DRONE_JOB_UUID': '887309d048'}, globalenv=globalenv),
]
# from https://github.com/boostorg/boost-ci
load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx")
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
-38
View File
@@ -1,38 +0,0 @@
#!/bin/bash
set -ex
export TRAVIS_BUILD_DIR=$(pwd)
export DRONE_BUILD_DIR=$(pwd)
export TRAVIS_BRANCH=$DRONE_BRANCH
export VCS_COMMIT_ID=$DRONE_COMMIT
export GIT_COMMIT=$DRONE_COMMIT
export PATH=~/.local/bin:/usr/local/bin:$PATH
echo '==================================> BEFORE_INSTALL'
. .drone/before-install.sh
echo '==================================> 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
echo '==================================> BEFORE_SCRIPT'
. $DRONE_BUILD_DIR/.drone/before-script.sh
echo '==================================> SCRIPT'
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
./b2 libs/multi_index/test toolset=$TOOLSET cxxstd=$CXXSTD
echo '==================================> AFTER_SUCCESS'
. $DRONE_BUILD_DIR/.drone/after-success.sh
+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
+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()
+42 -4
View File
@@ -1,10 +1,48 @@
# Boost Multi-index Containers Library
Branch | Travis | Drone | AppVeyor | Regression tests
---------|--------|-------|----------|-----------------
develop | [![Build Status](https://travis-ci.com/boostorg/multi_index.svg?branch=develop)](https://travis-ci.com/boostorg/multi_index) | [![Build Status](https://drone.cpp.al/api/badges/boostorg/multi_index/status.svg?ref=refs/heads/develop)](https://drone.cpp.al/boostorg/multi_index) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/multi_index?branch=develop&svg=true)](https://ci.appveyor.com/project/joaquintides/multi-index) | [![Test Results](./test_results.svg)](https://www.boost.org/development/tests/develop/developer/multi_index.html)
master | [![Build Status](https://travis-ci.com/boostorg/multi_index.svg?branch=master)](https://travis-ci.com/boostorg/multi_index) | [![Build Status](https://drone.cpp.al/api/badges/boostorg/multi_index/status.svg?ref=refs/heads/master)](https://drone.cpp.al/boostorg/multi_index) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/multi_index?branch=master&svg=true)](https://ci.appveyor.com/project/joaquintides/multi-index) | [![Test Results](./test_results.svg)](https://www.boost.org/development/tests/master/developer/multi_index.html)
[![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).
+3 -3
View File
@@ -1,4 +1,4 @@
# Copyright 2003-2021 Joaquín M López Muñoz.
# 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)
@@ -15,7 +15,7 @@ branches:
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0,msvc-14.0
TOOLSET: msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
@@ -34,4 +34,4 @@ build: off
test_script:
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- b2 address-model=32 libs/multi_index/test toolset=%TOOLSET% %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
;
-402
View File
@@ -1,402 +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="#allocator_awareness">Allocator awareness</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="allocator_awareness">Allocator awareness</a></h2>
<p>
In pre-C++11 compilers or defective environments without proper
<a href="https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer">allocator
awareness</a> machinery (basically, <code>std::allocator_traits</code>),
Boost.MultiIndex behaves as if
<code>std::allocator_traits&lt;allocator_type>::propagate_on_container_*::value</code>
were <code>false</code> for all allocators.
</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 January 25th 2020</p>
<p>&copy; Copyright 2003-2020 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>
+1 -1
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
+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">
+11 -11
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
@@ -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>
@@ -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 April 18th 2020</p>
<p>Revised November 7th 2025</p>
<p>&copy; Copyright 2003-2020 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">
+148 -11
View File
@@ -199,7 +199,7 @@ 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.)
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;
@@ -308,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>
@@ -334,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>
@@ -439,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>.
@@ -465,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>
@@ -723,7 +745,7 @@ of the index.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<code>node_type extract(const key_type& x);</code>
<code>node_type extract(const key_type&amp; x);</code>
<blockquote>
<b>Effects:</b> Extracts the node of the first element
@@ -780,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>
@@ -916,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>,
@@ -1049,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>
@@ -1171,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>),
@@ -1218,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>
@@ -1237,9 +1374,9 @@ Sequenced indices
<br>
<p>Revised May 9th 2020</p>
<p>Revised March 15th 2024</p>
<p>&copy; Copyright 2003-2020 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">
+15 -32
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>
@@ -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 January 9th 2020</p>
<p>Revised October 25th 2025</p>
<p>&copy; Copyright 2003-2020 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">
+201 -192
View File
@@ -8,7 +8,7 @@
<link rel="start" href="../index.html">
<link rel="prev" href="rnd_indices.html">
<link rel="up" href="index.html">
<link rel="next" href="../compiler_specifics.html">
<link rel="next" href="../performance.html">
</head>
<body>
@@ -21,8 +21,8 @@ Random access indices
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
</a></div>
<div class="next_link"><a href="../compiler_specifics.html"><img src="../next.gif" alt="compiler specifics" border="0"><br>
Compiler specifics
<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>
@@ -776,7 +776,7 @@ lvalue reference to a non <code>const</code>-qualified type.
<blockquote>
<b>Requires:</b> <code>ChainedPtr</code> is a <a href="#chained_pointers">chained pointer</a>
type to <code>Value</code>.<br>
<b>Returns:</b> <code>PtrToFunction)(y)</code>, where <code>y</code> is the
<b>Returns:</b> <code>PtrToFunction(y)</code>, where <code>y</code> is the
object chained-pointed to by <code>x</code>.
</blockquote>
@@ -825,73 +825,73 @@ Type operator()(<br>
<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>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>KeyFromValue0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>KeyFromValuen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>KeyFromValues</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result</span><span class=special>;</span>
<span class=comment>// comparison operators for composite_key_result:</span>
<span class=comment>// comparison operators for composite_key_result:
<span class=comment>// <b>OP</b> is any of ==,&lt;,!=,&gt;,&gt;=,&lt;=</span>
// <b>OP</b> is any of ==,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <span class=identifier><b><i>OP</i></b></span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey1</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey2</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <span class=identifier><b><i>OP</i></b></span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <span class=identifier><b><i>OP</i></b></span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <span class=identifier><b><i>OP</i></b></span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&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=special>...</span> <span class=identifier>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <span class=identifier><b><i>OP</i></b></span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=comment>// equality functors:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Pred0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Predn</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Pred</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Preds</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_equal_to</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_equal_to</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_equal_to</span><span class=special>;</span> <span class=comment>// deprecated
<span class=comment>// comparison functors:</span>
// comparison functors:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Compare0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Comparen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Compares</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_compare</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_less</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_less</span><span class=special>;</span> <span class=comment>// deprecated</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_greater</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_greater</span><span class=special>;</span> <span class=comment>// deprecated
<span class=comment>// hash functors:</span>
// hash functors:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Hash0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Hashn</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Hash</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Hashes</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_hash</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_hash</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_hash</span><span class=special>;</span> <span class=comment>// deprecated</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
<span class=special>}</span> <span class=comment>// namespace boost</span>
<span class=special>}</span> <span class=comment>// namespace boost
<span class=comment>// specializations of external functors for composite_key_result:</span>
// specializations of external functors for composite_key_result:</span>
<span class=keyword>namespace</span> <span class=identifier>std</span><span class=special>{</span>
@@ -925,19 +925,23 @@ at compile time. The returned object is of type
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>KeyFromValue0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>KeyFromValuen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>KeyFromValues</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>KeyFromValue0</span><span class=special>,...,</span><span class=identifier>KeyFromValuen</span><span class=special>&gt;</span> <span class=identifier>key_extractor_tuple</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>composite_key</span><span class=special>&gt;</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>KeyFromValue</span><span class=special>,</span><span class=identifier>KeyFromValues</span><span class=special>...&gt;</span> <span class=identifier>key_extractor_tuple</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>composite_key</span><span class=special>&gt;</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=identifier>composite_key</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>KeyFromValue0</span><span class=special>&amp;</span> <span class=identifier>k0</span><span class=special>=</span><span class=identifier>KeyFromValue0</span><span class=special>(),</span>
<span class=special>...</span>
<span class=keyword>const</span> <span class=identifier>KeyFromValuen</span><span class=special>&amp;</span> <span class=identifier>kn</span><span class=special>=</span><span class=identifier>KeyFromValuen</span><span class=special>());</span>
<span class=comment>// only provided if number of arguments is not greater than the number
// of elements and each args<sub>i</sub>&amp;&amp; is convertible to const KeyFromValues<sub>i</sub>&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>composite_key</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>composite_key</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_extractor_tuple</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// only provided if number of elements is not greater than
// the maximum length of a boost::tuple</span>
<span class=identifier>composite_key</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>KeyFromValue</span><span class=special>,</span><span class=identifier>KeyFromValues</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>const</span> <span class=identifier>key_extractor_tuple</span><span class=special>&amp;</span> <span class=identifier>key_extractors</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>key_extractor_tuple</span><span class=special>&amp;</span> <span class=identifier>key_extractors</span><span class=special>()</span>
@@ -953,14 +957,12 @@ at compile time. The returned object is of type
</pre></blockquote>
<p>
<code>KeyFromValue0</code>, ... , <code>KeyFromValuen</code> are the types of
<code>KeyFromValue</code> and <code>KeyFromValues...</code> are the types of
the key extractors combined into the composite key. Each of these types
must be a <a href="#key_extractors"><code>Key Extractor</code></a> from
<code>Value</code>. At least a key extractor must be provided. The maximum
number of key extractors of a <code>composite_key</code> instantiation is
implementation defined. <code>composite_key</code> internally stores an
<code>Value</code>. <code>composite_key</code> internally stores an
object of every constituent key extractor type.
<code>composite_key&lt;Value,KeyFromValue0,...,KeyFromValuen></code> is a model
<code>composite_key&lt;Value,KeyFromValue,KeyFromValues...></code> is a model
of:
<ul>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
@@ -980,18 +982,19 @@ of:
<h4><code>composite_key</code> members</h4>
<code>composite_key(<br>
&nbsp;&nbsp;const KeyFromValue0&amp; k0=KeyFromValue0(),<br>
&nbsp;&nbsp;...<br>
&nbsp;&nbsp;const KeyFromValuen&amp; kn=KeyFromValuen());
<code>template&lt;typename... Args><br>
composite_key(Args&amp;&amp;... args)
</code>
<blockquote>
<b>Effects:</b> Constructs a <code>composite_key</code> that stores
copies of the key extractor objects supplied.
copies of <code>const KeyFromValue&amp;</code>, <code>const KeyFromValues&amp;...</code>
values each obtained from the respective value of <code>std::forward&lt;Args>(args)...</code>.
</blockquote>
<code>composite_key(const key_extractor_tuple&amp; x);</code>
<code>composite_key(const key_extractor_tuple&amp; x);<br>
composite_key(const boost::tuple&lt;KeyFromValue,KeyFromValues...>&amp; x);
</code>
<blockquote>
<b>Effects:</b> Constructs a <code>composite_key</code> that stores
@@ -1073,19 +1076,19 @@ instantiations as their extracted key.
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
</pre></blockquote>
@@ -1111,7 +1114,7 @@ we use the following notation:
<code>x</code>,</li>
<li><code>v(x)</code> is the object of type <code>CompositeKey::value_type</code>
associated to <code>x</code>,</li>
<li><code>k<sub>i</sub>(x) = ck(x).key_extractors().get&lt;i>()</code>,
<li><code>k<sub>i</sub>(x) = get&lt;i>(ck(x).key_extractors())</code>,
that is, is the <code>i</code>-th key extractor of <code>ck(x)</code>,</li>
<li><code>x<sub>i</sub> = k<sub>i</sub>(x)(v(x))</code>, that is, the
key extracted from <code>v(x)</code> by the <code>i</code>-th key extractor,</li>
@@ -1134,17 +1137,17 @@ template&lt;typename CompositeKey,typename... Values><br>
bool operator==(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; y);<br>
template&lt;typename CompositeKey,typename... Values><br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator==(<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y);<br>
template&lt;typename CompositeKey,typename Value0,...,typename Valuen><br>
template&lt;typename CompositeKey,typename... Values><br>
bool operator==(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; y);<br>
template&lt;typename Value0,...,typename Valuen,typename CompositeKey><br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; y);<br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator==(<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y);
</code>
@@ -1160,7 +1163,7 @@ in <code>[0,length(x))</code>.
<b>Complexity:</b> No more key extraction operations and comparisons
are performed than those necessary for the evaluation of the expression above,
starting at <code>i==0</code>. The evaluation is short-circuited as soon as
the result is determined to be <code>false</code>.
the result is determined.
</blockquote>
<code>template&lt;typename CompositeKey1,typename CompositeKey2><br>
@@ -1171,17 +1174,17 @@ template&lt;typename CompositeKey,typename... Values><br>
bool operator<(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; y);<br>
template&lt;typename CompositeKey,typename... Values><br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator<(<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y);<br>
template&lt;typename CompositeKey,typename Value0,...,typename Valuen><br>
template&lt;typename CompositeKey,typename... Values><br>
bool operator<(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; y);<br>
template&lt;typename Value0,...,typename Valuen,typename CompositeKey><br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; y);<br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator<(<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y);
</code>
@@ -1212,17 +1215,17 @@ template&lt;typename CompositeKey,typename... Values><br>
bool operator <b><i>OP</i></b>(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; y);<br>
template&lt;typename CompositeKey,typename... Values><br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator <b><i>OP</i></b>(<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y);<br>
template&lt;typename CompositeKey,typename Value0,...,typename Valuen><br>
template&lt;typename CompositeKey,typename... Values><br>
bool operator <b><i>OP</i></b>(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; y);<br>
template&lt;typename Value0,...,typename Valuen,typename CompositeKey><br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; y);<br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator <b><i>OP</i></b>(<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y);
</code>
@@ -1233,7 +1236,7 @@ bool operator <b><i>OP</i></b>(<br>
<blockquote>
<b>Requires:</b> The expressions given below are valid (for the particular
<code><b><i>OP</i></b></code> considered.)<br>
<code><b><i>OP</i></b></code> considered).<br>
<b>Returns:</b> <code>true</code> if and only if
<blockquote>
<code>!(x==y)</code> (<code><b><i>OP</i></b></code> is <code>!=</code>),<br>
@@ -1256,20 +1259,24 @@ collection of elementary equality predicates.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Pred0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Predn</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Pred</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Preds</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_equal_to</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Pred0</span><span class=special>,...,</span><span class=identifier>Predn</span><span class=special>&gt;</span> <span class=identifier>key_eq_tuple</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Pred</span><span class=special>,</span><span class=identifier>Preds</span><span class=special>...&gt;</span> <span class=identifier>key_eq_tuple</span><span class=special>;</span>
<span class=identifier>composite_key_equal_to</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>Pred0</span><span class=special>&amp;</span> <span class=identifier>p0</span><span class=special>=</span><span class=identifier>Pred0</span><span class=special>(),</span>
<span class=special>...</span>
<span class=keyword>const</span> <span class=identifier>Predn</span><span class=special>&amp;</span> <span class=identifier>pn</span><span class=special>=</span><span class=identifier>Predn</span><span class=special>());</span>
<span class=comment>// only provided if number of arguments is not greater than the number
// of elements and each args<sub>i</sub>&amp;&amp; is convertible to const Preds<sub>i</sub>&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>composite_key_equal_to</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>composite_key_equal_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_eq_tuple</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// only provided if number of elements is not greater than
// the maximum length of a boost::tuple</span>
<span class=identifier>composite_key_equal_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Pred</span><span class=special>,</span><span class=identifier>Preds</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>const</span> <span class=identifier>key_eq_tuple</span><span class=special>&amp;</span> <span class=identifier>key_eqs</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>key_eq_tuple</span><span class=special>&amp;</span> <span class=identifier>key_eqs</span><span class=special>()</span><span class=special>;</span>
<span class=identifier>key_eq_tuple</span><span class=special>&amp;</span> <span class=identifier>key_eqs</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
@@ -1281,37 +1288,35 @@ collection of elementary equality predicates.
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>Pred0</code>, ... , <code>Predn</code> are the types of the equality
<code>Pred</code>, <code>Preds...</code> are the types of the equality
binary predicates stored by <code>composite_key_equal_to</code>. Each of these predicates
must be <code>CopyConstructible</code> and <code>CopyAssignable</code>. At least an
equality predicate must be provided. The maximum number of equality predicates of
a <code>composite_key_equal_to</code> instantiation is implementation defined.
must be <code>CopyConstructible</code> and <code>CopyAssignable</code>.
<code>composite_key_equal_to</code> is
<code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also <code>DefaultConstructible</code>
if each <code>Predi</code> is <code>DefaultConstructible</code> in its turn.
if each <code>Preds<sub>i</sub></code> is <code>DefaultConstructible</code> in its turn.
</p>
<p>
Note that formally it is not required that the <code>Predi</code> types
Note that formally it is not required that the <code>Pred</code>, <code>Preds...</code> types
behave as equality predicates in any definite way. However, the
semantics of <code>composite_key_equal_to</code> is well defined if this
is the case, as explained in the section on the
@@ -1326,18 +1331,19 @@ introduced for <code>composite_key_result</code>.
<h4><code>composite_key_equal_to</code> members</h4>
<code>composite_key_equal_to(<br>
&nbsp;&nbsp;const Pred0&amp; p0=Pred0(),<br>
&nbsp;&nbsp;...<br>
&nbsp;&nbsp;const Predn&amp; pn=Predn());
<code>template&lt;typename... Args><br>
composite_key_equal_to(Args&amp;&amp;... args);
</code>
<blockquote>
<b>Effects:</b> Constructs a <code>composite_key_equal_to</code> that stores
copies of the equality predicates supplied.
copies of <code>const Pred&amp;</code>, <code>const Preds&amp;...</code> values each
obtained from the respective values of <code>std::forward&lt;Arg>(args)...</code>.
</blockquote>
<code>composite_key_equal_to(const key_eq_tuple&amp; x);</code>
<code>composite_key_equal_to(const key_eq_tuple&amp; x);<br>
composite_key_equal_to(const boost::tuple&lt;Pred,Preds...>&amp; x);
</code>
<blockquote>
<b>Effects:</b> Constructs a <code>composite_key_equal_to</code> that stores
@@ -1369,34 +1375,34 @@ template&lt;typename CompositeKey,typename Values...><br>
bool operator()(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; y)const;<br>
template&lt;typename CompositeKey,typename Values...><br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator()(<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y)const;<br>
template&lt;typename CompositeKey,typename Value0,...,typename Valuen><br>
template&lt;typename CompositeKey,typename... Values><br>
bool operator()(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; y)const;<br>
template&lt;typename Value0,...,typename Valuen,typename CompositeKey><br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; y)const;<br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator()(<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y)const;<br>
</code>
<blockquote>
<b>Requires:</b> <code>length(x)==length(y)</code>. The expressions
<code>key_eqs().get&lt;i>()(x<sub>i</sub>,y<sub>i</sub>)</code> and
<code>key_eqs().get&lt;i>()(y<sub>i</sub>,x<sub>i</sub>)</code>
<code>get&lt;i>(key_eqs())(x<sub>i</sub>,y<sub>i</sub>)</code> and
<code>get&lt;i>(key_eqs())(y<sub>i</sub>,x<sub>i</sub>)</code>
are valid for all <code>i</code> in <code>[0,length(x))</code>.<br>
<b>Returns:</b> <code>true</code> if and only
<blockquote>
<code>key_eqs().get&lt;i>()(x<sub>i</sub>,y<sub>i</sub>)</code>
<code>get&lt;i>(key_eqs())(x<sub>i</sub>,y<sub>i</sub>)</code>
for all <code>i</code> in <code>[0,length(x))</code>.<br>
</blockquote>
<b>Complexity:</b> No more key extraction operations and comparisons
are performed than those necessary for the evaluation of the expression above,
starting at <code>i==0</code>. The evaluation is short-circuited as soon as
the result is determined to be <code>false</code>.
the result is determined.
</blockquote>
<h4><a name="composite_key_result_equal_to">Class template
@@ -1439,19 +1445,19 @@ are instantiations of <code>std::equal_to</code>.
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Values</span><span class=special>...,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Values</span><span class=special>...,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
@@ -1491,20 +1497,24 @@ collection of elementary comparison predicates.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Compare0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Comparen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Compares</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_compare</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Compare0</span><span class=special>,...,</span><span class=identifier>Comparen</span><span class=special>&gt;</span> <span class=identifier>key_comp_tuple</span><span class=special>;</span>
<span class=identifier>composite_key_compare</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>Compare0</span><span class=special>&amp;</span> <span class=identifier>c0</span><span class=special>=</span><span class=identifier>Compare0</span><span class=special>(),</span>
<span class=special>...</span>
<span class=keyword>const</span> <span class=identifier>Comparen</span><span class=special>&amp;</span> <span class=identifier>cn</span><span class=special>=</span><span class=identifier>Comparen</span><span class=special>());</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Compares</span><span class=special>...&gt;</span> <span class=identifier>key_comp_tuple</span><span class=special>;</span>
<span class=comment>// only provided if number of arguments is not greater than the number
// of elements and each args<sub>i</sub>&amp;&amp; is convertible to const Compares<sub>i</sub>&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>composite_key_compare</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>composite_key_compare</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_comp_tuple</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// only provided if number of elements is not greater than
// the maximum length of a boost::tuple</span>
<span class=identifier>composite_key_compare</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Compares</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>const</span> <span class=identifier>key_comp_tuple</span><span class=special>&amp;</span> <span class=identifier>key_comps</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>key_comp_tuple</span><span class=special>&amp;</span> <span class=identifier>key_comps</span><span class=special>()</span><span class=special>;</span>
<span class=identifier>key_comp_tuple</span><span class=special>&amp;</span> <span class=identifier>key_comps</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
@@ -1516,19 +1526,19 @@ collection of elementary comparison predicates.
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>&gt;</span>
@@ -1542,20 +1552,18 @@ collection of elementary comparison predicates.
</pre></blockquote>
<p>
<code>Compare0</code>, ... , <code>Comparen</code> are the types of the comparison
<code>Compare</code>, <code>Compares...</code> are the types of the comparison
binary predicates stored by <code>composite_key_compare</code>. Each of these predicates must be
<code>CopyConstructible</code> and <code>CopyAssignable</code>. At least a
comparison predicate must be provided. The maximum number of comparison predicates of
a <code>composite_key_compare</code> instantiation is implementation defined.
<code>CopyConstructible</code> and <code>CopyAssignable</code>
<code>composite_key_compare</code> is
<code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also
<code>DefaultConstructible</code>
if each <code>Comparei</code> is <code>DefaultConstructible</code> in its turn.
if each <code>Compares<sub>i</sub></code> is <code>DefaultConstructible</code> in its turn.
</p>
<p>
Note that formally it is not required that the <code>Comparei</code> types
Note that formally it is not required that the <code>Compare</code>, <code>Compares...</code> types
behave as comparison predicates in any definite way. However, the
semantics of <code>composite_key_compare</code> is well defined if this
is the case, as explained in the section on the
@@ -1570,18 +1578,19 @@ introduced for <code>composite_key_result</code>.
<h4><code>composite_key_compare</code> members</h4>
<code>composite_key_compare(<br>
&nbsp;&nbsp;const Compare0&amp; c0=Compare0(),<br>
&nbsp;&nbsp;...<br>
&nbsp;&nbsp;const Comparen&amp; cn=Comparen());
<code>template&lt;typename... Args><br>
composite_key_compare(Args&amp;&amp;... args);
</code>
<blockquote>
<b>Effects:</b> Constructs a <code>composite_key_compare</code> that stores
copies of the comparison predicates supplied.
copies of <code>const Compare&amp;</code>, <code>const Compares&amp;...</code>
values each obtained from the respective values of <code>std::forward&lt;Arg>(args)...</code>.
</blockquote>
<code>composite_key_compare(const key_comp_tuple&amp; x);</code>
<code>composite_key_compare(const key_comp_tuple&amp; x);<br>
composite_key_compare(const boost::tuple&lt;Compare,Compares...>&amp; x)
</code>
<blockquote>
<b>Effects:</b> Constructs a <code>composite_key_compare</code> that stores
@@ -1613,38 +1622,38 @@ template&lt;typename CompositeKey,typename... Values><br>
bool operator()(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; y)const;<br>
template&lt;typename CompositeKey,typename... Values><br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator()(<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y)const;<br>
template&lt;typename CompositeKey,typename Value0,...,typename Valuen><br>
template&lt;typename CompositeKey,typename... Values><br>
bool operator()(<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; y)const;<br>
template&lt;typename Value0,...,typename Valuen,typename CompositeKey><br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; y)const;<br>
template&lt;typename... Values,typename CompositeKey><br>
bool operator()(<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; x,<br>
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; x,<br>
&nbsp;&nbsp;const composite_key_result&lt;CompositeKey>&amp; y)const;<br>
</code>
<blockquote>
<b>Requires:</b> The expressions
<code>key_comps().get&lt;i>()(x<sub>i</sub>,y<sub>i</sub>)</code> and
<code>key_comps().get&lt;i>()(y<sub>i</sub>,x<sub>i</sub>)</code>
<code>get&lt;i>(key_comps())(x<sub>i</sub>,y<sub>i</sub>)</code> and
<code>get&lt;i>(key_comps())(y<sub>i</sub>,x<sub>i</sub>)</code>
are valid for all <code>i</code>
in <code>[0,min(length(x),length(y)))</code>.<br>
<b>Returns:</b> <code>true</code> if and only if there exists some
<code>j</code> in the range <code>[0,min(length(x),length(y)))</code>
such that
<blockquote>
<code>!key_comps().get&lt;i>()(x<sub>i</sub>,y<sub>i</sub>) &amp;&amp; !key_comps().get&lt;i>()(y<sub>i</sub>,x<sub>i</sub>)</code>
<code>!get&lt;i>(key_comps())(x<sub>i</sub>,y<sub>i</sub>) &amp;&amp; !get&lt;i>(key_comps())(y<sub>i</sub>,x<sub>i</sub>)</code>
for all <code>i</code> in <code>[0,j)</code>,<br>
<code>&nbsp;key_comps().get&lt;j>()(x<sub>j</sub>,y<sub>j</sub>)</code>.
<code>&nbsp;get&lt;j>(key_comps())(x<sub>j</sub>,y<sub>j</sub>)</code>.
</blockquote>
<b>Complexity:</b> No more key extraction operations and comparisons
are performed than those necessary for the evaluation of the expression above,
starting at <code>i==0</code>. The evaluation is short-circuited as soon as
the result is determined to be <code>false</code>.
the result is determined.
</blockquote>
<code>
@@ -1719,19 +1728,19 @@ instantiations of <code>std::less</code>.
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>&gt;</span>
@@ -1779,7 +1788,6 @@ an instantiation of <code>composite_key_result</code>, behaves as a particulariz
are instantiations of <code>std::greater</code>.
</p>
<blockquote><pre>
<span class=keyword>namespace</span> <span class=identifier>std</span><span class=special>{</span>
@@ -1802,19 +1810,19 @@ are instantiations of <code>std::greater</code>.
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Values</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>y</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</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>Values</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>&gt;</span>
@@ -1863,20 +1871,24 @@ instantiations based on a collection of elementary hash functors.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Hash0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Hashn</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Hash</span><span class=special>,</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Hashes</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_hash</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Hash0</span><span class=special>,...,</span><span class=identifier>Hashn</span><span class=special>&gt;</span> <span class=identifier>key_hasher_tuple</span><span class=special>;</span>
<span class=identifier>composite_key_hash</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>Hash0</span><span class=special>&amp;</span> <span class=identifier>h0</span><span class=special>=</span><span class=identifier>Hash0</span><span class=special>(),</span>
<span class=special>...</span>
<span class=keyword>const</span> <span class=identifier>Hashn</span><span class=special>&amp;</span> <span class=identifier>hn</span><span class=special>=</span><span class=identifier>Hashn</span><span class=special>());</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Hash</span><span class=special>,</span><span class=identifier>Hashes</span><span class=special>...&gt;</span> <span class=identifier>key_hasher_tuple</span><span class=special>;</span>
<span class=comment>// only provided if number of arguments is not greater than the number
// of elements and each args<sub>i</sub>&amp;&amp; is convertible to const Hashes<sub>i</sub>&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>composite_key_hash</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>composite_key_hash</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_hasher_tuple</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// only provided if number of elements is not greater than
// the maximum length of a boost::tuple</span>
<span class=identifier>composite_key_hash</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Hash</span><span class=special>,</span><span class=identifier>Hashes</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>const</span> <span class=identifier>key_hasher_tuple</span><span class=special>&amp;</span> <span class=identifier>key_hash_functions</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>key_hasher_tuple</span><span class=special>&amp;</span> <span class=identifier>key_hash_functions</span><span class=special>()</span><span class=special>;</span>
<span class=identifier>key_hasher_tuple</span><span class=special>&amp;</span> <span class=identifier>key_hash_functions</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span>
@@ -1886,24 +1898,22 @@ instantiations based on a collection of elementary hash functors.
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</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>Values</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>Hash0</code>, ... , <code>Hashn</code> are the types of the hash unary function objects
<code>Hash</code>, <code>Hashes...</code> are the types of the hash unary function objects
stored by <code>composite_key_hash</code>. Each of these objects
must be <code>CopyConstructible</code> and <code>CopyAssignable</code>
and return a value of type <code>std::size_t</code> in the range
[0, <code>std::numeric_limits&lt;std::size_t&gt;::max())</code>).
At least a hash functor must be provided. The maximum number of hash functors of
a <code>composite_key_hash</code> instantiation is implementation defined.
<code>composite_key_hash</code> is
<code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also <code>DefaultConstructible</code>
if each <code>Hashi</code> is <code>DefaultConstructible</code> in its turn.
if each <code>Hash</code>, <code>Hashes...</code> is <code>DefaultConstructible</code> in its turn.
</p>
<h4>Notation</h4>
@@ -1914,18 +1924,19 @@ introduced for <code>composite_key_result</code>.
<h4><code>composite_key_hash</code> members</h4>
<code>composite_key_hash(<br>
&nbsp;&nbsp;const Hash0&amp; h0=Hash0(),<br>
&nbsp;&nbsp;...<br>
&nbsp;&nbsp;const Hashn&amp; hn=Hashn());
<code>template&lt;typename... Args><br>
composite_key_hash(Args&amp;&amp;... args);
</code>
<blockquote>
<b>Effects:</b> Constructs a <code>composite_key_hash</code> that stores
copies of the hash functors supplied.
copies of <code>const Hash&amp;</code>, <code>const Hashes&amp;...</code>
values each obtained from the respective values of <code>std::forward&lt;Args>(args)...</code>.
</blockquote>
<code>composite_key_hash(const key_hasher_tuple&amp; x);</code>
<code>composite_key_hash(const key_hasher_tuple&amp; x);<br>
composite_key_hash(const boost::tuple&lt;Hash,Hashes...>&amp; x);
</code>
<blockquote>
<b>Effects:</b> Constructs a <code>composite_key_hash</code> that stores
@@ -1955,23 +1966,23 @@ bool operator()(<br>
template&lt;typename... Values><br>
bool operator()(<br>
&nbsp;&nbsp;const std::tuple&lt;Values...>&amp; x)const;<br>
template&lt;typename Value0,...,typename Valuen><br>
template&lt;typename... Values><br>
bool operator()(<br>
&nbsp;&nbsp;const boost::tuple&lt;Value0,...,Valuen>&amp; x)const;
&nbsp;&nbsp;const boost::tuple&lt;Values...>&amp; x)const;
</code>
<blockquote>
<b>Requires:</b> <code>length(x)==length(key_hash_functions())</code>.
The expression
<code>key_hash_functions().get&lt;i>()(x<sub>i</sub>)</code>
<code>get&lt;i>(key_hash_functions())(x<sub>i</sub>)</code>
is valid for all <code>i</code> in <code>[0,length(x))</code>.
<br>
<b>Returns:</b> A value in the range
<code>[0, std::numeric_limits&lt;std::size_t&gt;::max())</code> that
solely depends on the numerical tuple
<blockquote>
(<code>key_hash_functions().get&lt;0>()(x<sub>0</sub>)</code>, ... ,
<code>key_hash_functions().get&lt;N>()(x<sub>N</sub>)</code>),
(<code>get&lt;0>(key_hash_functions())(x<sub>0</sub>)</code>, ... ,
<code>get&lt;N>(key_hash_functions())(x<sub>N</sub>)</code>),
with <code>N=length(x)-1</code>.
</blockquote>
</blockquote>
@@ -2012,9 +2023,9 @@ are instantiations of
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</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>Values</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Values</span><span class=special>...&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
<span class=special>}</span> <span class=comment>// namespace boost</span>
@@ -2078,7 +2089,7 @@ with respect to <code>composite_key_result&lt;CompositeKey></code>:
<blockquote>
<code>tuple&lt;Q0,...,Qj></code>,<br>
<code>composite_key_result&lt;composite_key&lt;K0,...,Kj> ></code>, with
<code>Ki::result_type = Qi</code> for all <code>i = 0,...,j</code>.
<code>Ki::result_type = Qi</code> for all <code>i = 0,...,j</code>,
</blockquote>
provided that each <code>Qi</code> is either <code>Ti</code> or a
<a href="hash_indices.html#lookup"><code>Compatible Key</code></a>
@@ -2097,9 +2108,9 @@ is lexicographical. Also, the following types are
<code>composite_key_compare</code> with respect to
<code>composite_key_result&lt;CompositeKey></code>:
<blockquote>
<code>tuple&lt;Q0,...,Qk></code>, <code>k &lt;= n</code><br>
<code>tuple&lt;Q0,...,Qk></code>, <code>k &lt;= n</code>,<br>
<code>composite_key_result&lt;composite_key&lt;K0,...,Kk> ></code>, with
<code>Ki::result_type = Qi</code> for all <code>i = 0,...,k</code>.
<code>Ki::result_type = Qi</code> for all <code>i = 0,...,k</code>,
</blockquote>
provided that
<ul>
@@ -2163,9 +2174,7 @@ subsets of those associated to <code>!(x&lt;y)&amp;&amp;!(y&lt;x)</code>.
<p>
In C++17 compliant environments, <code>key</code> provides a very terse syntax for
the specification of Boost.MultiIndex predefined key extractors. The number of template
arguments passed to <code>key</code> must be greater than zero and not exceed the
maximum number of key extractors accepted by
<a href="#composite_key"><code>composite_key</code></a>. <code>key&lt;Key&gt;</code>
arguments passed to <code>key</code> must be greater than zero. <code>key&lt;Key&gt;</code>
resolves to:
<ul>
<li><a href="#member"><code>member&lt;Class,Type,Key&gt;</code></a>
@@ -2214,7 +2223,7 @@ and engenders undefined behavior otherwise. When passed two or more arguments,
with:
<ul>
<li><code>KeyFromValuei</code> = <code>key&lt;Keyi&gt;</code>
for all <code>i = 0,...,n</code>
for all <code>i = 0,...,n</code>,
</li>
<li><code>Value</code> = <code>std::decay_t&lt;Value0&gt;</code> &#8855;
<code>std::decay_t&lt;Value1&gt;</code> &#8855; &middot;&middot;&middot; &#8855;
@@ -2237,15 +2246,15 @@ Random access indices
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
</a></div>
<div class="next_link"><a href="../compiler_specifics.html"><img src="../next.gif" alt="compiler specifics" border="0"><br>
Compiler specifics
<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 April 19th 2020</p>
<p>Revised November 7th 2025</p>
<p>&copy; Copyright 2003-2020 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">
+30 -40
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>
@@ -389,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>
@@ -400,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>
@@ -411,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>
@@ -422,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>
@@ -531,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>.
@@ -556,8 +552,11 @@ 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.
@@ -598,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>
@@ -621,11 +614,8 @@ 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>
@@ -738,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
@@ -765,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>.
@@ -777,7 +767,7 @@ of the <code>multi_index_container</code> is preserved as well.<br>
<blockquote>
<b>Effects:</b> Constructs a <code>multi_index_container</code> by transferring the
elements of <code>x</code> and copying its internal objects (those specified
in <code>ctor_args_list</code> and the allocator.)<br>
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>
@@ -883,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>
@@ -965,7 +955,7 @@ typename nth_index&lt;N>::type::iterator project(IteratorType it);</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>
@@ -995,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>
@@ -1011,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>
@@ -1053,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>
@@ -1063,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>
@@ -1082,9 +1072,9 @@ Index reference
<br>
<p>Revised May 9th 2020</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2020 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">
+139 -8
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,7 +196,7 @@ 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.)
(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;
@@ -310,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>
@@ -329,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>
@@ -427,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
@@ -460,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>
@@ -715,7 +741,7 @@ of the index.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<code>node_type extract(const key_type& x);</code>
<code>node_type extract(const key_type&amp; x);</code>
<blockquote>
<b>Effects:</b> Extracts the node of the first element
@@ -906,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>,
@@ -995,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>
@@ -1017,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>
@@ -1193,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>
@@ -1210,9 +1341,9 @@ Ranked indices
<br>
<p>Revised May 9th 2020</p>
<p>Revised February 5th 2022</p>
<p>&copy; Copyright 2003-2020 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">
+143 -63
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>
@@ -177,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
@@ -316,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>
@@ -432,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>
@@ -450,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>
@@ -533,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>
@@ -573,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>
@@ -875,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>
@@ -973,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>;
@@ -996,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>;
@@ -1143,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>
@@ -1160,9 +1240,9 @@ Key extraction
<br>
<p>Revised May 9th 2020</p>
<p>Revised August 30th 2021</p>
<p>&copy; Copyright 2003-2020 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">
+142 -62
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>
@@ -299,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>
@@ -420,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>
@@ -508,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>
@@ -802,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>
@@ -906,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>;
@@ -929,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>;
@@ -1078,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>
@@ -1095,9 +1175,9 @@ Random access indices
<br>
<p>Revised May 9th 2020</p>
<p>Revised August 30th 2021</p>
<p>&copy; Copyright 2003-2020 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">
+194 -6
View File
@@ -30,6 +30,17 @@ 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>
@@ -63,12 +74,190 @@ 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/basics.html#node_handling">node extraction and insertion</a>
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.
@@ -334,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:
@@ -653,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>
@@ -675,9 +863,9 @@ Acknowledgements
<br>
<p>Revised June 6th 2020</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2020 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)
+5 -5
View File
@@ -55,7 +55,7 @@ with some of the least common features offered by Boost.MultiIndex.
<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 class="odd_tr">
@@ -73,7 +73,7 @@ with some of the least common features offered by Boost.MultiIndex.
<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 class="odd_tr">
<td><a href="../test/test_hash_ops.cpp"><code>test_hash_ops.cpp</code></a></td>
@@ -101,7 +101,7 @@ 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>
@@ -166,9 +166,9 @@ Future work
<br>
<p>Revised May 9th 2020</p>
<p>Revised October 26th 2025</p>
<p>&copy; Copyright 2003-2020 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 -77
View File
@@ -62,7 +62,6 @@ Index types
</ul>
</li>
<li><a href="#projection">Projection of iterators</a></li>
<li><a href="#node_handling">Node handling operations</a></li>
<li><a href="#complexity">Complexity and exception safety</a></li>
</ul>
@@ -115,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
@@ -269,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>
@@ -418,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>
@@ -454,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>
@@ -497,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).
@@ -767,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>.
@@ -802,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>
@@ -1217,72 +1216,6 @@ When provided, <code>project</code> can also be used with
<a href="#tagging">tags</a>.
</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>// 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>
<h2><a name="complexity">Complexity and exception safety</a></h2>
<p>
@@ -1296,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
@@ -1317,9 +1250,9 @@ Index types
<br>
<p>Revised May 9th 2020</p>
<p>Revised August 16th 2021</p>
<p>&copy; Copyright 2003-2020 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">
+24 -3
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>
@@ -162,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>
@@ -199,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>
@@ -240,9 +261,9 @@ Techniques
<br>
<p>Revised May 9th 2020</p>
<p>Revised June 27th 2026</p>
<p>&copy; Copyright 2003-2020 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:
+113 -5
View File
@@ -55,6 +55,7 @@ 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>
@@ -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>
@@ -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 6th 2018</p>
<p>Revised August 16th 2021</p>
<p>&copy; Copyright 2003-2018 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
@@ -494,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>
@@ -1126,9 +1126,9 @@ Container creation
<br>
<p>Revised April 19th 2020</p>
<p>Revised November 1st 2025</p>
<p>&copy; Copyright 2003-2020 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>
+2 -15
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of rearrange facilities.
*
* Copyright 2003-2020 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)
@@ -22,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;
@@ -197,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 */
@@ -1,173 +0,0 @@
/* 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)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_ALLOCATOR_TRAITS_HPP
#define BOOST_MULTI_INDEX_DETAIL_ALLOCATOR_TRAITS_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <boost/type_traits/is_empty.hpp>
#include <memory>
#else
#include <boost/detail/workaround.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_empty.hpp>
#include <new>
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* poor man's replacement of std::allocator_traits */
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<typename T> struct void_helper{typedef void type;};
template<typename Allocator,typename=void>
struct allocator_is_always_equal:boost::is_empty<Allocator>{};
template<typename Allocator>
struct allocator_is_always_equal<
Allocator,
typename void_helper<
typename std::allocator_traits<Allocator>::is_always_equal
>::type
>:std::allocator_traits<Allocator>::is_always_equal{};
template<typename Allocator>
struct allocator_traits:std::allocator_traits<Allocator>
{
/* wrap std::allocator_traits alias templates for use in C++03 codebase */
typedef std::allocator_traits<Allocator> super;
/* pre-C++17 compatibilty */
typedef allocator_is_always_equal<Allocator> is_always_equal;
template<typename T>
struct rebind_alloc
{
typedef typename super::template rebind_alloc<T> type;
};
template<typename T>
struct rebind_traits
{
typedef typename super::template rebind_traits<T> type;
};
};
#else
/* not a full std::allocator_traits rewrite (not needed) */
template<typename Allocator>
struct allocator_traits
{
typedef Allocator allocator_type;
typedef typename Allocator::value_type value_type;
typedef typename Allocator::pointer pointer;
typedef typename Allocator::const_pointer const_pointer;
/* [const_]void_pointer not provided as boost::pointer_traits's
* rebind_to has been seen to fail with things like
* boost::interprocess::offset_ptr in relatively old environments.
*/
typedef typename Allocator::difference_type difference_type;
typedef typename Allocator::size_type size_type;
typedef boost::false_type propagate_on_container_copy_assignment;
typedef boost::false_type propagate_on_container_move_assignment;
typedef boost::false_type propagate_on_container_swap;
typedef boost::is_empty<Allocator> is_always_equal;
template<typename T>
struct rebind_alloc
{
typedef typename Allocator::template rebind<T>::other type;
};
template<typename T>
struct rebind_traits
{
typedef allocator_traits<typename rebind_alloc<T>::type> type;
};
static pointer allocate(Allocator& a,size_type n){return a.allocate(n);}
static pointer allocate(Allocator& a,size_type n,const_pointer p)
/* should've been const_void_pointer p */
{return a.allocate(n,p);}
static void deallocate(Allocator& a,pointer p,size_type n)
{a.deallocate(p,n);}
template<typename T>
static void construct(Allocator&,T* p,const T& x)
{::new (static_cast<void*>(p)) T(x);}
template<typename T>
static void construct(Allocator&,T* p,BOOST_RV_REF(T) x)
{::new (static_cast<void*>(p)) T(boost::move(x));}
template<typename T,BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
static void construct(Allocator&,T* p,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
vartempl_placement_new(p,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
/* MSVC issues spurious warnings about unreferencend formal parameters in
* destroy<T> when T is a class with trivial dtor.
*/
#pragma warning(push)
#pragma warning(disable:4100)
#endif
template<typename T>
static void destroy(Allocator&,T* p){p->~T();}
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
#pragma warning(pop)
#endif
static size_type max_size(Allocator& a)BOOST_NOEXCEPT{return a.max_size();}
static Allocator select_on_container_copy_construction(const Allocator& a)
{
return a;
}
};
#endif
template<typename Allocator,typename T>
struct rebind_alloc_for
{
typedef typename allocator_traits<Allocator>::
template rebind_alloc<T>::type type;
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -0,0 +1,76 @@
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_ANY_CONTAINER_VIEW_HPP
#define BOOST_MULTI_INDEX_DETAIL_ANY_CONTAINER_VIEW_HPP
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* type-erased, non-owning view over a ConstIterator-container's range */
template<typename ConstIterator>
class any_container_view
{
public:
template<typename Container>
any_container_view(const Container& x):px(&x),pt(vtable_for<Container>()){}
const void* container()const{return px;}
ConstIterator begin()const{return pt->begin(px);}
ConstIterator end()const{return pt->end(px);}
private:
struct vtable
{
ConstIterator (*begin)(const void*);
ConstIterator (*end)(const void*);
};
template<typename Container>
static ConstIterator begin_for(const void* px)
{
return static_cast<const Container*>(px)->begin();
}
template<typename Container>
static ConstIterator end_for(const void* px)
{
return static_cast<const Container*>(px)->end();
}
template<typename Container>
vtable* vtable_for()
{
static vtable v=
{
&begin_for<Container>,
&end_for<Container>
};
return &v;
}
const void* px;
vtable* pt;
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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/core/no_exceptions_support.hpp>
#include <boost/noncopyable.hpp>
#include <boost/serialization/serialization.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();
@@ -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
+10 -12
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/core/noncopyable.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/multi_index/detail/adl_swap.hpp>
#include <boost/multi_index/detail/allocator_traits.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <memory>
@@ -46,18 +46,15 @@ namespace detail{
template<typename T,typename Allocator=std::allocator<T> >
struct auto_space:private noncopyable
{
typedef typename rebind_alloc_for<
Allocator,T>
::type allocator;
typedef allocator_traits<allocator> alloc_traits;
typedef typename alloc_traits::pointer pointer;
typedef typename alloc_traits::size_type size_type;
typedef allocator_rebind_t<Allocator,T> allocator;
typedef allocator_pointer_t<allocator> pointer;
typedef allocator_size_type_t<allocator> size_type;
explicit auto_space(const Allocator& al=Allocator(),size_type n=1):
al_(al),n_(n),data_(n_?alloc_traits::allocate(al_,n_):pointer(0))
al_(al),n_(n),data_(n_?allocator_allocate(al_,n_):pointer(0))
{}
~auto_space(){if(n_)alloc_traits::deallocate(al_,data_,n_);}
~auto_space(){if(n_)allocator_deallocate(al_,data_,n_);}
Allocator get_allocator()const{return al_;}
@@ -68,7 +65,8 @@ struct auto_space:private noncopyable
swap(
x,
boost::integral_constant<
bool,alloc_traits::propagate_on_container_swap::value>());
bool,
allocator_propagate_on_container_swap_t<allocator>::value>());
}
void swap(auto_space& x,boost::true_type /* swap_allocators */)
@@ -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-2018 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{
@@ -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-2020 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,10 +15,10 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/multi_index/detail/allocator_traits.hpp>
#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>
@@ -27,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
@@ -129,10 +129,10 @@ class bucket_array:bucket_array_base<>
{
typedef bucket_array_base<> super;
typedef hashed_index_base_node_impl<
typename rebind_alloc_for<
allocator_rebind_t<
Allocator,
char
>::type
>
> base_node_impl_type;
public:
@@ -224,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>
+13 -17
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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)
@@ -16,14 +16,13 @@
#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/no_exceptions_support.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/multi_index/detail/allocator_traits.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 <functional>
#include <utility>
namespace boost{
@@ -66,21 +65,18 @@ struct copy_map_value_copier
struct copy_map_value_mover
{
template<typename Value>
BOOST_RV_REF(Value) operator()(Value& x)const{return boost::move(x);}
Value&& operator()(Value& x)const{return std::move(x);}
};
template <typename Node,typename Allocator>
class copy_map:private noncopyable
{
typedef typename rebind_alloc_for<
Allocator,Node
>::type allocator_type;
typedef allocator_traits<allocator_type> alloc_traits;
typedef typename alloc_traits::pointer pointer;
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 typename alloc_traits::size_type size_type;
typedef const copy_map_entry<Node>* const_iterator;
typedef allocator_size_type_t<allocator_type> size_type;
copy_map(
const Allocator& al,size_type size,Node* header_org,Node* header_cpy):
@@ -92,7 +88,7 @@ public:
{
if(!released){
for(size_type i=0;i<n;++i){
alloc_traits::destroy(
allocator_destroy(
al_,boost::addressof((spc.data()+i)->second->value()));
deallocate((spc.data()+i)->second);
}
@@ -128,12 +124,12 @@ private:
pointer allocate()
{
return alloc_traits::allocate(al_,1);
return allocator_allocate(al_,1);
}
void deallocate(Node* node)
{
alloc_traits::deallocate(al_,static_cast<pointer>(node),1);
allocator_deallocate(al_,static_cast<pointer>(node),1);
}
template<typename ValueAccess>
@@ -142,7 +138,7 @@ private:
(spc.data()+n)->first=node;
(spc.data()+n)->second=raw_ptr<Node*>(allocate());
BOOST_TRY{
alloc_traits::construct(
allocator_construct(
al_,boost::addressof((spc.data()+n)->second->value()),
access(node->value()));
}
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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)
@@ -6,7 +6,9 @@
* See http://www.boost.org/libs/multi_index for library home page.
*/
#include <boost/config.hpp>
#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)
+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-2020 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{
@@ -67,15 +66,19 @@ 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>
@@ -89,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);
}
}
@@ -102,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);
}
}
}
@@ -119,7 +122,7 @@ public:
typedef Node node_type;
Node* get_node()const{return node;}
Node* get_node()const{return raw_ptr<Node*>(node);}
private:
@@ -133,7 +136,7 @@ private:
Node::template increment_local<IndexCategory>(node);
}
Node* node;
typename Node::pointer node;
};
template<
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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/multi_index/detail/allocator_traits.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <utility>
@@ -99,19 +99,17 @@ struct hashed_index_node_impl;
template<typename Allocator>
struct hashed_index_base_node_impl
{
typedef typename rebind_alloc_for<
typedef allocator_rebind_t<
Allocator,hashed_index_base_node_impl
>::type base_allocator;
typedef typename rebind_alloc_for<
> base_allocator;
typedef allocator_rebind_t<
Allocator,hashed_index_node_impl<Allocator>
>::type node_allocator;
typedef allocator_traits<base_allocator> base_alloc_traits;
typedef allocator_traits<node_allocator> node_alloc_traits;
typedef typename base_alloc_traits::pointer base_pointer;
typedef typename base_alloc_traits::const_pointer const_base_pointer;
typedef typename node_alloc_traits::pointer pointer;
typedef typename node_alloc_traits::const_pointer const_pointer;
typedef typename node_alloc_traits::difference_type difference_type;
> 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_;}
@@ -689,14 +687,14 @@ private:
template<typename Super>
struct hashed_index_node_trampoline:
hashed_index_node_impl<
typename rebind_alloc_for<
allocator_rebind_t<
typename Super::allocator_type,char
>::type
>
>
{
typedef typename rebind_alloc_for<
typedef allocator_rebind_t<
typename Super::allocator_type,char
>::type impl_allocator_type;
> impl_allocator_type;
typedef hashed_index_node_impl<impl_allocator_type> impl_type;
};
@@ -714,6 +712,13 @@ public:
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{
@@ -756,15 +761,15 @@ public:
/* interoperability with hashed_index_iterator */
template<typename Category>
static void increment(hashed_index_node*& x)
static void increment(pointer& x)
{
x=from_impl(node_alg<Category>::type::after(x->impl()));
x=pointer(from_impl(node_alg<Category>::type::after(x->impl())));
}
template<typename Category>
static void increment_local(hashed_index_node*& x)
static void increment_local(pointer& x)
{
x=from_impl(node_alg<Category>::type::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,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
+56 -26
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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)
@@ -15,16 +15,14 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/core/addressof.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/multi_index/detail/allocator_traits.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>
@@ -62,14 +60,12 @@ protected:
typedef multi_index_container<
Value,IndexSpecifierList,Allocator> final_type;
typedef tuples::null_type ctor_args_list;
typedef typename rebind_alloc_for<
Allocator,typename Allocator::value_type
>::type final_allocator_type;
typedef Allocator final_allocator_type;
typedef node_handle<
final_node_type,final_allocator_type> final_node_handle_type;
typedef mpl::vector0<> index_type_list;
typedef mpl::vector0<> iterator_type_list;
typedef mpl::vector0<> const_iterator_type_list;
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;
@@ -86,14 +82,19 @@ protected:
private:
typedef Value value_type;
typedef allocator_traits<Allocator> alloc_traits;
typedef typename alloc_traits::size_type size_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)
{}
@@ -119,7 +120,7 @@ protected:
{
x=final().allocate_node();
BOOST_TRY{
final().construct_value(x,boost::move(const_cast<value_type&>(v)));
final().construct_value(x,std::move(const_cast<value_type&>(v)));
}
BOOST_CATCH(...){
final().deallocate_node(x);
@@ -134,6 +135,15 @@ protected:
return x;
}
template<typename MultiIndexContainer>
final_node_type* insert_(
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)
{
@@ -152,7 +162,8 @@ protected:
return x;
}
void extract_(index_node_type*){}
template<typename Dst>
void extract_(index_node_type*,Dst){}
void clear_(){}
@@ -172,7 +183,7 @@ protected:
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;
}
@@ -203,6 +214,10 @@ 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_();}
@@ -222,11 +237,14 @@ protected:
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,12 +265,11 @@ protected:
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)
@@ -260,12 +277,25 @@ protected:
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-2016 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
@@ -105,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
@@ -1,4 +1,4 @@
/* Copyright 2003-2019 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)
@@ -16,8 +16,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)||\
BOOST_WORKAROUND(_LIBCPP_VERSION,<30700)||\
#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
@@ -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
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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)
@@ -16,14 +16,16 @@
#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/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/multi_index_container_fwd.hpp>
#include <boost/multi_index/detail/allocator_traits.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{
@@ -43,16 +45,12 @@ public:
typedef typename Node::value_type value_type;
typedef Allocator allocator_type;
private:
typedef allocator_traits<allocator_type> alloc_traits;
public:
node_handle()BOOST_NOEXCEPT:node(0){}
node_handle(BOOST_RV_REF(node_handle) x)BOOST_NOEXCEPT:node(x.node)
node_handle(node_handle&& x)BOOST_NOEXCEPT:node(x.node)
{
if(!x.empty()){
move_construct_allocator(boost::move(x));
move_construct_allocator(std::move(x));
x.destroy_allocator();
x.node=0;
}
@@ -66,15 +64,16 @@ public:
}
}
node_handle& operator=(BOOST_RV_REF(node_handle) x)
node_handle& operator=(node_handle&& x)
{
if(this!=&x){
if(!empty()){
delete_node();
if(!x.empty()){
BOOST_MULTI_INDEX_IF_CONSTEXPR(
alloc_traits::propagate_on_container_move_assignment::value){
move_assign_allocator(boost::move(x));
allocator_propagate_on_container_move_assignment_t<
allocator_type>::value){
move_assign_allocator(std::move(x));
}
x.destroy_allocator();
}
@@ -83,7 +82,7 @@ public:
}
}
else if(!x.empty()){
move_construct_allocator(boost::move(x));
move_construct_allocator(std::move(x));
x.destroy_allocator();
}
node=x.node;
@@ -109,24 +108,24 @@ public:
void swap(node_handle& x)
BOOST_NOEXCEPT_IF(
alloc_traits::propagate_on_container_swap::value||
alloc_traits::is_always_equal::value)
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(
alloc_traits::propagate_on_container_swap::value){
allocator_propagate_on_container_swap_t<allocator_type>::value){
using std::swap;
swap(*allocator_ptr(),*x.allocator_ptr());
}
}
else{
x.move_construct_allocator(boost::move(*this));
x.move_construct_allocator(std::move(*this));
destroy_allocator();
}
}
else if(!x.empty()){
move_construct_allocator(boost::move(x));
move_construct_allocator(std::move(x));
x.destroy_allocator();
}
std::swap(node,x.node);
@@ -139,8 +138,6 @@ public:
}
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle)
template <typename,typename,typename>
friend class boost::multi_index::multi_index_container;
@@ -171,30 +168,27 @@ private:
#include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
void move_construct_allocator(BOOST_RV_REF(node_handle) x)
void move_construct_allocator(node_handle&& x)
{
::new (static_cast<void*>(allocator_ptr()))
allocator_type(boost::move(*x.allocator_ptr()));
allocator_type(std::move(*x.allocator_ptr()));
}
void move_assign_allocator(BOOST_RV_REF(node_handle) x)
void move_assign_allocator(node_handle&& x)
{
*allocator_ptr()=boost::move(*x.allocator_ptr());
*allocator_ptr()=std::move(*x.allocator_ptr());
}
void destroy_allocator(){allocator_ptr()->~allocator_type();}
void delete_node()
{
typedef typename rebind_alloc_for<
allocator_type,Node
>::type node_allocator;
typedef detail::allocator_traits<node_allocator> node_alloc_traits;
typedef typename node_alloc_traits::pointer node_pointer;
typedef allocator_rebind_t<allocator_type,Node> node_allocator;
typedef allocator_pointer_t<node_allocator> node_pointer;
alloc_traits::destroy(*allocator_ptr(),boost::addressof(node->value()));
allocator_destroy(*allocator_ptr(),boost::addressof(node->value()));
node_allocator nal(*allocator_ptr());
node_alloc_traits::deallocate(nal,static_cast<node_pointer>(node),1);
allocator_deallocate(nal,static_cast<node_pointer>(node),1);
}
Node* node;
@@ -214,27 +208,33 @@ template<typename Iterator,typename NodeHandle>
struct insert_return_type
{
insert_return_type(
Iterator position_,bool inserted_,BOOST_RV_REF(NodeHandle) node_):
position(position_),inserted(inserted_),node(boost::move(node_)){}
insert_return_type(BOOST_RV_REF(insert_return_type) x):
position(x.position),inserted(x.inserted),node(boost::move(x.node)){}
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=(BOOST_RV_REF(insert_return_type) x)
insert_return_type& operator=(insert_return_type&& x)
{
position=x.position;
inserted=x.inserted;
node=boost::move(x.node);
node=std::move(x.node);
return *this;
}
Iterator position;
bool inserted;
NodeHandle node;
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type)
};
/* 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 */
+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
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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)
@@ -44,43 +44,35 @@
#include <algorithm>
#include <boost/call_traits.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/core/ref.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/multi_index/detail/adl_swap.hpp>
#include <boost/multi_index/detail/allocator_traits.hpp>
#include <boost/multi_index/detail/bidir_node_iterator.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/invalidate_iterators.hpp>
#include <boost/multi_index/detail/modify_key_adaptor.hpp>
#include <boost/multi_index/detail/node_handle.hpp>
#include <boost/multi_index/detail/ord_index_node.hpp>
#include <boost/multi_index/detail/ord_index_ops.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/type_list.hpp>
#include <boost/multi_index/detail/unbounded.hpp>
#include <boost/multi_index/detail/value_compare.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
#include <boost/ref.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_same.hpp>
#include <initializer_list>
#include <iterator>
#include <type_traits>
#include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/archive/archive_exception.hpp>
#include <boost/bind/bind.hpp>
#include <boost/multi_index/detail/bad_archive_exception.hpp>
#include <boost/multi_index/detail/duplicates_iterator.hpp>
#include <boost/throw_exception.hpp>
#endif
@@ -115,6 +107,11 @@ namespace detail{
struct ordered_unique_tag{};
struct ordered_non_unique_tag{};
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4355) /* this used in base member initializer list */
#endif
template<
typename KeyFromValue,typename Compare,
typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
@@ -125,25 +122,10 @@ template<
typename KeyFromValue,typename Compare,
typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
>
class ordered_index_impl:
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
,public safe_mode::safe_container<
ordered_index_impl<
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> >
#endif
class ordered_index_impl:protected SuperMeta::type
{
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
* lifetime of const references bound to temporaries --precisely what
* scopeguards are.
*/
#pragma parse_mfunc_templ off
#endif
/* cross-index access */
template <typename,typename,typename> friend class index_base;
typedef typename SuperMeta::type super;
@@ -171,26 +153,21 @@ public:
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
typedef safe_mode::safe_iterator<
bidir_node_iterator<index_node_type>,
ordered_index_impl> iterator;
bidir_node_iterator<index_node_type> > iterator;
#else
typedef bidir_node_iterator<index_node_type> iterator;
#endif
typedef iterator const_iterator;
private:
typedef allocator_traits<allocator_type> alloc_traits;
public:
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::difference_type difference_type;
typedef typename alloc_traits::pointer pointer;
typedef typename alloc_traits::const_pointer const_pointer;
typedef allocator_size_type_t<allocator_type> size_type;
typedef allocator_difference_type_t<
allocator_type> difference_type;
typedef allocator_pointer_t<allocator_type> pointer;
typedef allocator_const_pointer_t<allocator_type> const_pointer;
typedef typename
boost::reverse_iterator<iterator> reverse_iterator;
std::reverse_iterator<iterator> reverse_iterator;
typedef typename
boost::reverse_iterator<const_iterator> const_reverse_iterator;
std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef typename super::final_node_handle_type node_type;
typedef detail::insert_return_type<
iterator,node_type> insert_return_type;
@@ -201,18 +178,18 @@ protected:
typedef tuples::cons<
ctor_args,
typename super::ctor_args_list> ctor_args_list;
typedef typename mpl::push_front<
typedef type_list_push_front<
typename super::index_type_list,
ordered_index<
KeyFromValue,Compare,
SuperMeta,TagList,Category,AugmentPolicy
> >::type index_type_list;
typedef typename mpl::push_front<
>> index_type_list;
typedef type_list_push_front<
typename super::iterator_type_list,
iterator>::type iterator_type_list;
typedef typename mpl::push_front<
iterator> iterator_type_list;
typedef type_list_push_front<
typename super::const_iterator_type_list,
const_iterator>::type const_iterator_type_list;
const_iterator> const_iterator_type_list;
typedef typename super::copy_map_type copy_map_type;
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
@@ -222,8 +199,7 @@ protected:
protected:
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
typedef safe_mode::safe_container<
ordered_index_impl> safe_super;
typedef safe_mode::safe_container<iterator> safe_container;
#endif
typedef typename call_traits<
@@ -231,11 +207,9 @@ protected:
typedef typename call_traits<
key_type>::param_type key_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
/* needed to avoid commas in some macros */
typedef std::pair<iterator,bool> emplace_return_type;
typedef std::pair<iterator,bool> pair_return_type;
public:
@@ -261,13 +235,13 @@ public:
const_iterator
end()const BOOST_NOEXCEPT{return make_iterator(header());}
reverse_iterator
rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
rbegin()BOOST_NOEXCEPT{return reverse_iterator{end()};}
const_reverse_iterator
rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
rbegin()const BOOST_NOEXCEPT{return const_reverse_iterator{end()};}
reverse_iterator
rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
rend()BOOST_NOEXCEPT{return reverse_iterator{begin()};}
const_reverse_iterator
rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
rend()const BOOST_NOEXCEPT{return const_reverse_iterator{begin()};}
const_iterator
cbegin()const BOOST_NOEXCEPT{return begin();}
const_iterator
@@ -297,11 +271,27 @@ public:
/* modifiers */
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace,emplace_impl)
template<typename... Args>
std::pair<iterator,bool> emplace(Args&&... args)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_(std::forward<Args>(args)...);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
iterator,emplace_hint,emplace_hint_impl,iterator,position)
template<typename... Args>
iterator emplace_hint(iterator position,Args&&... args)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_hint_(
static_cast<final_node_type*>(position.get_node()),
std::forward<Args>(args)...);
return make_iterator(p.first);
}
std::pair<iterator,bool> insert(const value_type& x)
{
@@ -310,7 +300,7 @@ public:
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
std::pair<iterator,bool> insert(value_type&& x)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
@@ -327,7 +317,7 @@ public:
return make_iterator(p.first);
}
iterator insert(iterator position,BOOST_RV_REF(value_type) x)
iterator insert(iterator position,value_type&& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@@ -341,30 +331,23 @@ public:
void insert(InputIterator first,InputIterator last)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
index_node_type* hint=header(); /* end() */
for(;first!=last;++first){
hint=this->final_insert_ref_(
*first,static_cast<final_node_type*>(hint)).first;
index_node_type::increment(hint);
}
for(;first!=last;++first)this->final_insert_ref_(*first);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(std::initializer_list<value_type> list)
{
insert(list.begin(),list.end());
}
#endif
insert_return_type insert(BOOST_RV_REF(node_type) nh)
insert_return_type insert(node_type&& nh)
{
if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
return insert_return_type(make_iterator(p.first),p.second,std::move(nh));
}
iterator insert(const_iterator position,BOOST_RV_REF(node_type) nh)
iterator insert(const_iterator position,node_type&& nh)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@@ -438,7 +421,7 @@ public:
x,static_cast<final_node_type*>(position.get_node()));
}
bool replace(iterator position,BOOST_RV_REF(value_type) x)
bool replace(iterator position,value_type&& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@@ -529,6 +512,75 @@ public:
this->final_clear_();
}
template<typename Index>
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
merge(Index& x)
{
merge(x,x.begin(),x.end());
}
template<typename Index>
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
merge(Index&& x){merge(static_cast<Index&>(x));}
template<typename Index>
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
ordered_index_impl,Index,pair_return_type)
merge(Index& x,typename Index::iterator i)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
if(x.end().get_node()==this->header()){ /* same container */
return std::pair<iterator,bool>(
make_iterator(static_cast<final_node_type*>(i.get_node())),true);
}
else{
std::pair<final_node_type*,bool> p=this->final_transfer_(
x,static_cast<final_node_type*>(i.get_node()));
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
}
template<typename Index>
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
ordered_index_impl,Index,pair_return_type)
merge(Index&& x,typename Index::iterator i)
{
return merge(static_cast<Index&>(x),i);
}
template<typename Index>
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
merge(
Index& x,
typename Index::iterator first,
typename Index::iterator last)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
if(x.end().get_node()!=this->header()){ /* different containers */
this->final_transfer_range_(x,first,last);
}
}
template<typename Index>
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
merge(
Index&& x,
typename Index::iterator first,
typename Index::iterator last)
{
merge(static_cast<Index&>(x),first,last);
}
/* observers */
key_from_value key_extractor()const{return key;}
@@ -568,6 +620,19 @@ public:
return n;
}
template<typename CompatibleKey>
bool contains(const CompatibleKey& x)const
{
return contains(x,comp_);
}
template<typename CompatibleKey,typename CompatibleCompare>
bool contains(
const CompatibleKey& x,const CompatibleCompare& comp)const
{
return find(x,comp)!=end();
}
template<typename CompatibleKey>
iterator lower_bound(const CompatibleKey& x)const
{
@@ -624,43 +689,51 @@ public:
std::pair<iterator,iterator>
range(LowerBounder lower,UpperBounder upper)const
{
typedef typename mpl::if_<
typedef typename mp11::mp_if<
is_same<LowerBounder,unbounded_type>,
BOOST_DEDUCED_TYPENAME mpl::if_<
mp11::mp_if<
is_same<UpperBounder,unbounded_type>,
both_unbounded_tag,
lower_unbounded_tag
>::type,
BOOST_DEDUCED_TYPENAME mpl::if_<
>,
mp11::mp_if<
is_same<UpperBounder,unbounded_type>,
upper_unbounded_tag,
none_unbounded_tag
>::type
>::type dispatch;
>
> dispatch;
return range(lower,upper,dispatch());
}
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al):
super(args_list.get_tail(),al),
protected:
ordered_index_impl(
const ctor_args_list& args_list,
const allocator_type& al,index_node_type* h):
super(args_list.get_tail(),al,h),
key(tuples::get<0>(args_list.get_head())),
comp_(tuples::get<1>(args_list.get_head()))
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
,safe(*this)
#endif
{
empty_initialize();
}
ordered_index_impl(
const ordered_index_impl<
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x):
super(x),
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super(),
#endif
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
const allocator_type& al,index_node_type* h):
super(x,al,h),
key(x.key),
comp_(x.comp_)
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
,safe(*this)
#endif
{
/* Copy ctor just takes the key and compare objects from x. The rest is
* done in a subsequent call to copy_().
@@ -670,15 +743,16 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
ordered_index_impl(
const ordered_index_impl<
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
const allocator_type& al,index_node_type* h,
do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()),
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super(),
#endif
super(x,al,h,do_not_copy_elements_tag()),
key(x.key),
comp_(x.comp_)
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
,safe(*this)
#endif
{
empty_initialize();
}
@@ -690,9 +764,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
iterator make_iterator(index_node_type* node)
{return iterator(node,this);}
{return iterator(node,&safe);}
const_iterator make_iterator(index_node_type* node)const
{return const_iterator(node,const_cast<ordered_index_impl*>(this));}
{return const_iterator(node,const_cast<safe_container*>(&safe));}
#else
iterator make_iterator(index_node_type* node){return iterator(node);}
const_iterator make_iterator(index_node_type* node)const
@@ -796,14 +870,15 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
return res;
}
void extract_(index_node_type* x)
template<typename Dst>
void extract_(index_node_type* x,Dst dst)
{
node_impl_type::rebalance_for_extract(
x->impl(),header()->parent(),header()->left(),header()->right());
super::extract_(x);
super::extract_(x,dst.next());
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
detach_iterators(x);
transfer_iterators(dst.get(),x);
#endif
}
@@ -818,7 +893,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
empty_initialize();
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::detach_dereferenceable_iterators();
safe.detach_dereferenceable_iterators();
#endif
}
@@ -832,7 +907,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
adl_swap(comp_,x.comp_);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
safe.swap(x.safe);
#endif
super::swap_(x,swap_allocators);
@@ -843,7 +918,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
{
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
safe.swap(x.safe);
#endif
super::swap_elements_(x);
@@ -885,7 +960,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
b=in_place(x->value(),x,Category());
}
BOOST_CATCH(...){
extract_(x);
extract_(x,invalidate_iterators());
BOOST_RETHROW;
}
BOOST_CATCH_END
@@ -895,7 +970,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
BOOST_TRY{
link_info inf;
if(!link_point(key(x->value()),inf,Category())){
super::extract_(x);
super::extract_(x,invalidate_iterators());
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
detach_iterators(x);
@@ -905,7 +980,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
}
BOOST_CATCH(...){
super::extract_(x);
super::extract_(x,invalidate_iterators());
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
detach_iterators(x);
@@ -1259,31 +1334,15 @@ private:
iterator it=make_iterator(x);
safe_mode::detach_equivalent_iterators(it);
}
template<typename Dst>
void transfer_iterators(Dst& dst,index_node_type* x)
{
iterator it=make_iterator(x);
safe_mode::transfer_equivalent_iterators(dst,it);
}
#endif
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
iterator emplace_hint_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_hint_(
static_cast<final_node_type*>(position.get_node()),
BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return make_iterator(p.first);
}
template<typename LowerBounder,typename UpperBounder>
std::pair<iterator,iterator>
range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
@@ -1417,9 +1476,7 @@ private:
}
else if(comp_(key(x->value()),key(position->value()))){
/* inconsistent rearrangement */
throw_exception(
archive::archive_exception(
archive::archive_exception::other_exception));
throw_exception(bad_archive_exception());
}
else index_node_type::increment(position);
@@ -1436,9 +1493,8 @@ protected: /* for the benefit of AugmentPolicy::augmented_interface */
key_from_value key;
key_compare comp_;
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
#pragma parse_mfunc_templ reset
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_container safe;
#endif
};
@@ -1460,6 +1516,10 @@ class ordered_index:
SuperMeta,TagList,Category,AugmentPolicy
>
>::type super;
protected:
typedef typename super::index_node_type index_node_type;
public:
typedef typename super::ctor_args_list ctor_args_list;
typedef typename super::allocator_type allocator_type;
@@ -1476,26 +1536,33 @@ public:
return *this;
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
ordered_index& operator=(
std::initializer_list<BOOST_DEDUCED_TYPENAME super::value_type> list)
std::initializer_list<typename super::value_type> list)
{
this->final()=list;
return *this;
}
#endif
protected:
ordered_index(
const ctor_args_list& args_list,const allocator_type& al):
super(args_list,al){}
const ctor_args_list& args_list,
const allocator_type& al,index_node_type* h):
super(args_list,al,h){}
ordered_index(const ordered_index& x):super(x){}
ordered_index(
const ordered_index& x,const allocator_type& al,index_node_type* h):
super(x,al,h){}
ordered_index(const ordered_index& x,do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()){}
ordered_index(
const ordered_index& x,const allocator_type& al,index_node_type* h,
do_not_copy_elements_tag):
super(x,al,h,do_not_copy_elements_tag()){}
};
#if defined(BOOST_MSVC)
#pragma warning(pop) /* C4355 */
#endif
/* comparison */
template<
@@ -1623,16 +1690,22 @@ void swap(
/* Boost.Foreach compatibility */
namespace boost{
namespace foreach{
template<typename>
struct is_noncopyable;
template<
typename KeyFromValue,typename Compare,
typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
>
inline boost::mpl::true_* boost_foreach_is_noncopyable(
struct is_noncopyable<
boost::multi_index::detail::ordered_index<
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&,
boost_foreach_argument_dependent_lookup_hack)
{
return 0;
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>
>:std::true_type{};
}
}
#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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/multi_index/detail/allocator_traits.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>
@@ -70,15 +69,14 @@ struct ordered_index_node_impl; /* fwd decl. */
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_traits
{
typedef typename rebind_alloc_for<
typedef allocator_rebind_t<
Allocator,
ordered_index_node_impl<AugmentPolicy,Allocator>
>::type allocator;
typedef allocator_traits<allocator> alloc_traits;
typedef typename alloc_traits::pointer pointer;
typedef typename alloc_traits::const_pointer const_pointer;
typedef typename alloc_traits::difference_type difference_type;
typedef typename alloc_traits::size_type size_type;
> 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>
@@ -133,6 +131,7 @@ 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;
typedef const ordered_index_node_impl<
@@ -228,7 +227,7 @@ 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>
@@ -238,7 +237,7 @@ struct ordered_index_node_impl_base:
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<
@@ -580,18 +579,18 @@ template<typename AugmentPolicy,typename Super>
struct ordered_index_node_trampoline:
ordered_index_node_impl<
AugmentPolicy,
typename rebind_alloc_for<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
>
{
typedef ordered_index_node_impl<
AugmentPolicy,
typename rebind_alloc_for<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
> impl_type;
};
@@ -610,6 +609,14 @@ public:
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();}
@@ -648,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-2017 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,6 +15,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#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
@@ -30,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 */
@@ -43,9 +44,7 @@ struct promotes_2nd_arg:mpl::false_{};
#else
#include <boost/mpl/and.hpp>
#include <boost/mpl/bool.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>
>
+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 */
@@ -1,4 +1,4 @@
/* Copyright 2003-2018 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,11 +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/multi_index/detail/allocator_traits.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>
namespace boost{
@@ -44,10 +44,10 @@ class random_access_index_loader_base:private noncopyable
{
protected:
typedef random_access_index_node_impl<
typename rebind_alloc_for<
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;
@@ -93,8 +93,7 @@ protected:
}
private:
typedef allocator_traits<Allocator> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef allocator_size_type_t<Allocator> size_type;
void preprocess()
{
@@ -1,4 +1,4 @@
/* Copyright 2003-2018 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,9 +14,9 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/core/allocator_access.hpp>
#include <algorithm>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multi_index/detail/allocator_traits.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
#include <cstddef>
#include <functional>
@@ -30,18 +30,16 @@ namespace detail{
template<typename Allocator>
struct random_access_index_node_impl
{
typedef typename rebind_alloc_for<
typedef allocator_rebind_t<
Allocator,random_access_index_node_impl
>::type node_allocator;
typedef allocator_traits<node_allocator> node_alloc_traits;
typedef typename node_alloc_traits::pointer pointer;
typedef typename node_alloc_traits::const_pointer const_pointer;
typedef typename node_alloc_traits::difference_type difference_type;
typedef typename rebind_alloc_for<
> 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 ptr_allocator;
typedef allocator_traits<ptr_allocator> ptr_alloc_traits;
typedef typename ptr_alloc_traits::pointer ptr_pointer;
> ptr_allocator;
typedef allocator_pointer_t<ptr_allocator> ptr_pointer;
ptr_pointer& up(){return up_;}
ptr_pointer up()const{return up_;}
@@ -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 rebind_alloc_for<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
>
{
typedef random_access_index_node_impl<
typename rebind_alloc_for<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
> impl_type;
};
@@ -198,11 +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::difference_type difference_type;
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();}
@@ -237,25 +261,25 @@ 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,difference_type 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 difference_type distance(
@@ -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-2020 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,11 +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/multi_index/detail/allocator_traits.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>
namespace boost{
@@ -32,20 +32,21 @@ template<typename Allocator>
class random_access_index_ptr_array:private noncopyable
{
typedef random_access_index_node_impl<
typename rebind_alloc_for<
allocator_rebind_t<
Allocator,
char
>::type
>
> node_impl_type;
public:
typedef typename node_impl_type::pointer value_type;
typedef typename rebind_alloc_for<
typedef allocator_rebind_t<
Allocator,value_type
>::type value_allocator;
typedef allocator_traits<value_allocator> alloc_traits;
typedef typename alloc_traits::pointer pointer;
typedef typename alloc_traits::size_type size_type;
> 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_,size_type sz):
@@ -1,4 +1,4 @@
/* Copyright 2003-2018 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{
@@ -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>
@@ -1,4 +1,4 @@
/* Copyright 2003-2018 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,8 +15,9 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/core/pointer_traits.hpp>
#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{
@@ -45,7 +46,7 @@ ranked_node_size(Pointer x)
template<typename Pointer>
inline Pointer ranked_index_nth(
BOOST_DEDUCED_TYPENAME ranked_node_size_type<Pointer>::type n,Pointer end_)
typename ranked_node_size_type<Pointer>::type n,Pointer end_)
{
typedef typename ranked_node_size_type<Pointer>::type size_type;
@@ -96,7 +97,7 @@ inline typename Node::size_type 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> >());
}
@@ -107,10 +108,10 @@ template<
>
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<
@@ -119,7 +120,7 @@ template<
>
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;
@@ -162,10 +163,10 @@ template<
>
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<
@@ -174,7 +175,7 @@ template<
>
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;
@@ -215,10 +216,10 @@ template<
>
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<
@@ -227,7 +228,7 @@ template<
>
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;
@@ -260,7 +261,7 @@ 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> >());
}
@@ -272,10 +273,10 @@ template<
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<
@@ -285,11 +286,11 @@ template<
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)
{
typedef typename Node::size_type size_type;
if(!top)return std::pair<size_type,size_type>(0,0);
if(!top)return std::pair<size_type,size_type>((size_type)0,(size_type)0);
size_type s=top->impl()->size;
@@ -304,12 +305,12 @@ ranked_index_equal_range_rank(
}
else{
return std::pair<size_type,size_type>(
s-top->impl()->size+
(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);
+203 -92
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2020 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), \
@@ -113,18 +118,20 @@
#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/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{
@@ -162,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>
@@ -217,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)
{
@@ -233,6 +273,12 @@ inline bool check_different_container(
return &cont0!=&cont1;
}
template<typename Container1,typename Container2>
inline bool check_different_container(const Container1&,const Container2&)
{
return true;
}
template<typename Container0,typename Container1>
inline bool check_equal_allocators(
const Container0& cont0,const Container1& cont1)
@@ -240,42 +286,20 @@ inline bool check_equal_allocators(
return cont0.get_allocator()==cont1.get_allocator();
}
/* 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.
*/
/* fwd decls */
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
template<typename Container> class safe_container;
template<typename Iterator> void detach_equivalent_iterators(Iterator&);
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();
}
}
namespace safe_mode_detail{
template<typename Container> class safe_container; /* fwd decl. */
/* fwd decls */
} /* namespace multi_index::safe_mode */
namespace detail{
class safe_container_base; /* fwd decl. */
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
{
@@ -324,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_);
@@ -345,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()
{
@@ -405,41 +430,36 @@ 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){}
@@ -451,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 */
@@ -529,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
@@ -547,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;
@@ -570,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-2020 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/core/no_exceptions_support.hpp>
#include <boost/mpl/if.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-2019 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/multi_index/detail/allocator_traits.hpp>
#include <boost/multi_index/detail/raw_ptr.hpp>
namespace boost{
@@ -29,13 +29,14 @@ namespace detail{
template<typename Allocator>
struct sequenced_index_node_impl
{
typedef typename rebind_alloc_for<
typedef allocator_rebind_t<
Allocator,sequenced_index_node_impl
>::type node_allocator;
typedef allocator_traits<node_allocator> alloc_traits;
typedef typename alloc_traits::pointer pointer;
typedef typename alloc_traits::const_pointer const_pointer;
typedef typename alloc_traits::difference_type difference_type;
> 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_;}
@@ -132,17 +133,17 @@ private:
template<typename Super>
struct sequenced_index_node_trampoline:
sequenced_index_node_impl<
typename rebind_alloc_for<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
>
{
typedef sequenced_index_node_impl<
typename rebind_alloc_for<
allocator_rebind_t<
typename Super::allocator_type,
char
>::type
>
> impl_type;
};
@@ -157,6 +158,13 @@ public:
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-2020 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)
@@ -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;
@@ -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 */

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