Compare commits
561 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b6a0722f11 | |||
| fbeaf88056 | |||
| 19237f650a | |||
| 0356be0f6f | |||
| 1f61ddc1ec | |||
| 0d48b7d14b | |||
| ac4971abc2 | |||
| a47c9f57b4 | |||
| d260b4e524 | |||
| 179b5def1e | |||
| eb993b1e23 | |||
| 890f032939 | |||
| e2b50ef729 | |||
| c2aca0975e | |||
| 280d659bd9 | |||
| f4045037fa | |||
| 07eb41065d | |||
| 1da523aaf8 | |||
| 60ff77c181 | |||
| 47d36ce8e2 | |||
| 162318b931 | |||
| e27a02aa81 | |||
| 5c17744f34 | |||
| 2b2c52a27f | |||
| 343cb4c6f3 | |||
| 3ad3171006 | |||
| f8143b9ff9 | |||
| 0e55b48789 | |||
| b6d5c88629 | |||
| 7d8e20a59b | |||
| 6163f59747 | |||
| 4259987765 | |||
| 28e00a0ea6 | |||
| 92de0326b5 | |||
| 00abbbdb27 | |||
| c42c2509bc | |||
| eeac86a37e | |||
| 40bead0430 | |||
| 4312c88ead | |||
| a7716c7f16 | |||
| ae95816ae8 | |||
| 2404754d42 | |||
| 45bb3c8b70 | |||
| 99f33def00 | |||
| ed8d49dc59 | |||
| 6b2be7c601 | |||
| fba66b0538 | |||
| a7e5cf843a | |||
| 647a60da24 | |||
| 2b78a77d6b | |||
| 9847e2daf8 | |||
| 7c591a13aa | |||
| 7c3cb66008 | |||
| 2026b94c12 | |||
| 0179c2c041 | |||
| d86df5a52f | |||
| 5c8b26cd9b | |||
| 1b38fdcc77 | |||
| a52810fc3d | |||
| 2a2282b270 | |||
| 1ab207ccc7 | |||
| 647af59bdd | |||
| 5623d2b9e2 | |||
| 3dad7f38a4 | |||
| 436c60cd09 | |||
| 23779b1577 | |||
| b3815602b2 | |||
| 2f5c1b5fb5 | |||
| fa84d6f1ae | |||
| 028d097cd9 | |||
| 060c2951aa | |||
| d410fd952a | |||
| bd2f183055 | |||
| 2eb53f67e2 | |||
| 32dfab2f9c | |||
| 2546cb99bc | |||
| bd1cb7d171 | |||
| 59a4416a6e | |||
| 4795ae9d89 | |||
| b685e11dfc | |||
| 9d1813aaad | |||
| ece90a6eb4 | |||
| 1b1e29d6e3 | |||
| 53c11e1ea7 | |||
| e3fec3af57 | |||
| ed5a975059 | |||
| 2271c1b9c6 | |||
| 4a109e99e5 | |||
| f8945d113e | |||
| 85b6cdba91 | |||
| 98091f99e6 | |||
| ff3f612abb | |||
| 99430f9edd | |||
| e69466039d | |||
| a766a08573 | |||
| 3a47a82947 | |||
| a34c774a05 | |||
| 382e41fa99 | |||
| 2374136ea8 | |||
| ffbdc49bf2 | |||
| 1c3ef66798 | |||
| 61c732118e | |||
| d7ad9185e8 | |||
| 81dbe86f25 | |||
| 3e8928834c | |||
| adbb136e43 | |||
| ff46d35312 | |||
| a8d34a56f7 | |||
| 89b4ff7bbf | |||
| c9a21d79d6 | |||
| d4e81bbe7e | |||
| 264c062bf4 | |||
| 3caea31bfc | |||
| a7ef250b9f | |||
| 7508edc5c2 | |||
| c24b639df1 | |||
| de709d6048 | |||
| 68d3e4b5b2 | |||
| c98519ca41 | |||
| e49ae2b4c2 | |||
| 32b7f257c2 | |||
| 54302463e5 | |||
| 55fb849c2c | |||
| bbb915bd34 | |||
| 8ef40b12df | |||
| 1933ca91b7 | |||
| 09ea3b91be | |||
| 9504362e08 | |||
| 5ecffb12b6 | |||
| 8dbab1978c | |||
| a611e3c504 | |||
| abf7c456e1 | |||
| 58f39df261 | |||
| cd8124a9d6 | |||
| f2922dd541 | |||
| 6de959eb78 | |||
| 454266c22c | |||
| 6698843328 | |||
| dc1ac9d879 | |||
| adbd496248 | |||
| 008b1a5ed6 | |||
| ac377a6e7d | |||
| 131e3427ae | |||
| e45fdaa2ca | |||
| 1af32b3ad0 | |||
| e38e118acf | |||
| 255a53240d | |||
| a199da8fb0 | |||
| 521b3bee9e | |||
| c57a6771fd | |||
| 9acee043bc | |||
| ec129437dc | |||
| 8136196a4d | |||
| d9c62ea8ed | |||
| edf9492ee1 | |||
| 26aa66b779 | |||
| ecad16693f | |||
| f11bacdbbc | |||
| 18cea285e2 | |||
| d6cd661119 | |||
| c1889e33dc | |||
| cfbf3f6fdc | |||
| e86162cff8 | |||
| 4f06b28a77 | |||
| a3bf0de25b | |||
| 45266cd2a7 | |||
| 26f85dfea8 | |||
| fe746a187c | |||
| 35ba93a0eb | |||
| 135b31fc3c | |||
| 504574a265 | |||
| e8c1598e32 | |||
| 72d4b74cfb | |||
| f31407d621 | |||
| 0ac225601d | |||
| 7cc508376c | |||
| 69488c737b | |||
| 7b77621323 | |||
| 9623bf0a7d | |||
| 4d21e89621 | |||
| 4753b325c5 | |||
| 97e015d2e2 | |||
| 350d337348 | |||
| 36b17f6de6 | |||
| 2f21af1751 | |||
| 91f2116711 | |||
| 58c42a46c1 | |||
| 8a8dee1357 | |||
| 5c5b1e95d4 | |||
| 7eb3b609d8 | |||
| 5744230acf | |||
| 3613e2287b | |||
| 18d6e7525a | |||
| 7999b663aa | |||
| cd2db772ea | |||
| bc5a3bdb67 | |||
| 07749abe6f | |||
| 53607ec851 | |||
| b9a4467f34 | |||
| 43d835120e | |||
| 3e1095d609 | |||
| df022fa659 | |||
| 4a5c4fc1a1 | |||
| b469742547 | |||
| 1f29a85e42 | |||
| a63646f567 | |||
| e23ffaa1f3 | |||
| c055516320 | |||
| 62dbfff9c8 | |||
| 096741d58b | |||
| 8a2703ff2b | |||
| 1db23a5f1c | |||
| 1f4d33012b | |||
| 84e70f08f2 | |||
| acda0c8abd | |||
| 10e6c0ef87 | |||
| 64848d0397 | |||
| bbad86c193 | |||
| ee364b7150 | |||
| b7e4086682 | |||
| 14257ba9ce | |||
| 14c16a3bae | |||
| 09afa8aa99 | |||
| f4c9492a54 | |||
| 0181f7dd8e | |||
| 8ece62829b | |||
| 4ee43076b8 | |||
| a26d889584 | |||
| 3f8d49acea | |||
| cff87caa7c | |||
| 6b64f02cd3 | |||
| c26c180916 | |||
| 23113b4dd6 | |||
| a4563aa66f | |||
| b0068335bb | |||
| d0a7194db7 | |||
| 07977932ea | |||
| 7683cec919 | |||
| 19505ffa5f | |||
| ca05a953bd | |||
| c3cbe4df42 | |||
| c5770230bf | |||
| 85625ecd5d | |||
| c41fad927a | |||
| 27eea86ff9 | |||
| 9732279d77 | |||
| f471d61d0b | |||
| e18ece1ec1 | |||
| d45c8e0991 | |||
| 08fe6a360a | |||
| 71fd63ce7a | |||
| 57ab570240 | |||
| 2170318c39 | |||
| 6aae9471bb | |||
| 79541fce51 | |||
| 87ff899ceb | |||
| 6d6bb75504 | |||
| 87cb3fe3ad | |||
| 3547ed34b8 | |||
| c389bd462f | |||
| d0feaa8963 | |||
| f6ef739fc9 | |||
| a9c06ce5c1 | |||
| 26d215e063 | |||
| 97187ae449 | |||
| 1f450f5322 | |||
| 67cb8a2f9b | |||
| a5d2e189ff | |||
| 86d7b3ef6e | |||
| 3239677c40 | |||
| 802543fd94 | |||
| fdd4934c23 | |||
| 041c9ec779 | |||
| 121977f5a4 | |||
| 5b45403d9a | |||
| a37acffb89 | |||
| 2e1ba3df49 | |||
| a01876551b | |||
| 41f29cd238 | |||
| d5db77efa5 | |||
| d338464a11 | |||
| 7d04e36f00 | |||
| 2cc3436492 | |||
| 2a822dd1d1 | |||
| 3bff1885d1 | |||
| 27923b8620 | |||
| add77e70c3 | |||
| 38bb0ed41c | |||
| f64736a9a6 | |||
| b4733fb78a | |||
| 86a69d7cd8 | |||
| de188091f2 | |||
| b036cfdb49 | |||
| 9b580ad95a | |||
| 8616eb47c1 | |||
| fd153213ec | |||
| f5ae9390cf | |||
| d73379b055 | |||
| 8dfd2f9e64 | |||
| 590e3d1511 | |||
| c564f8f5dd | |||
| 078944b1b5 | |||
| 527f4a5061 | |||
| 0bc802ad7d | |||
| 83a3b450ae | |||
| 72410dc3c6 | |||
| ef90efe473 | |||
| 25f76950f4 | |||
| 84c65c35cb | |||
| 209c1afd04 | |||
| 2935086121 | |||
| fe328c2800 | |||
| 3e92a5b2a8 | |||
| 80a10c2d72 | |||
| d2f0ef79a2 | |||
| 0d4bf54658 | |||
| 0f583940c9 | |||
| 9b0382bde3 | |||
| 76931bdbd3 | |||
| 6452e4db53 | |||
| b35a722129 | |||
| 2ef40ef45a | |||
| 67f9c5b3ab | |||
| 867a0fb9c9 | |||
| 026fab85aa | |||
| bac508586e | |||
| 71fbbf1754 | |||
| 84e34e45c3 | |||
| 1186efb3f0 | |||
| f0c0ae11a8 | |||
| ebb7d18ce6 | |||
| 3e9d0232d2 | |||
| 55723474d2 | |||
| 1bf606a75d | |||
| 768432afcb | |||
| 48eab15fc0 | |||
| 7b1bcc810d | |||
| 13842a23dc | |||
| 78a83060f7 | |||
| e4771a0fae | |||
| bf08ab429c | |||
| a739892808 | |||
| eb1f2a98b7 | |||
| 80517e00d7 | |||
| 215d795984 | |||
| 4223235333 | |||
| efce67f27b | |||
| 5fd288b095 | |||
| 9dfc424d7a | |||
| 588e7657f3 | |||
| 270d048f12 | |||
| 604128d17a | |||
| 4c3b315b0b | |||
| d2efd9d5ed | |||
| b185884ffe | |||
| 6b58056716 | |||
| f88fb07ae8 | |||
| 7d1417fe8c | |||
| 718559b87f | |||
| 12ba0771e8 | |||
| fd2b4ede68 | |||
| 5e50c69465 | |||
| 180f64dc11 | |||
| ff51956131 | |||
| 86059ad43f | |||
| b14efa6fbf | |||
| 3199ff1b44 | |||
| 9c8c001d5d | |||
| 06b509b35c | |||
| 45adb9c08a | |||
| 436ea292c6 | |||
| a5210bff85 | |||
| 1eebcfcf5f | |||
| 6d2c3985f0 | |||
| 8290474391 | |||
| d3e74bc941 | |||
| f5976c1695 | |||
| c80e451d22 | |||
| b61b58abfa | |||
| 90bc0b7662 | |||
| 5d016b4003 | |||
| 11f09a3558 | |||
| 03ebcdd0f4 | |||
| d026f22be0 | |||
| 62911d5198 | |||
| 8c5ac57c6a | |||
| 05e70771fd | |||
| df5eb5b646 | |||
| 6b5f74732b | |||
| c2d5785ae8 | |||
| a404be8a6b | |||
| ebf92487ae | |||
| 47b98dd304 | |||
| bd8ea1bc86 | |||
| d881480b52 | |||
| 15accb2836 | |||
| 93da3b3f29 | |||
| 78f6bf5446 | |||
| faf18a55f0 | |||
| aebc21ee44 | |||
| 0468378c0d | |||
| 9b4c07478c | |||
| ff403f0a62 | |||
| efd8ea14ef | |||
| 58fd64b622 | |||
| f83aa3c780 | |||
| 26ce890ff8 | |||
| c4a9b8f8e6 | |||
| 3a4ac5c0a4 | |||
| ae87c1d454 | |||
| 40634a5f23 | |||
| 16778f3ff3 | |||
| 47b172ab68 | |||
| 1434c7d727 | |||
| 33e19c4ce1 | |||
| 47079d4620 | |||
| d6932847ec | |||
| 543fbad471 | |||
| 88a418d563 | |||
| 5d2015ed2e | |||
| 16325e6039 | |||
| add267a90a | |||
| 7be686f18e | |||
| de9febb387 | |||
| 8bdf62586f | |||
| 6fa0f070b9 | |||
| 1130b76e4b | |||
| 93d21ea64c | |||
| 2e22bed967 | |||
| 28930f64c0 | |||
| 6418bd5e83 | |||
| 88f3a9ca8b | |||
| 8e573eba2c | |||
| e46279d9ec | |||
| 2e361f8b6a | |||
| 259f87b550 | |||
| 99284aa1c5 | |||
| bbeb058580 | |||
| 5cd33a9a81 | |||
| c41ded0890 | |||
| 252398ac13 | |||
| 0c0acfaa3f | |||
| 64b5247bea | |||
| bcec2c0467 | |||
| c6e0231bed | |||
| c757629a6d | |||
| 5c5ca84a23 | |||
| 14d94f24fa | |||
| 18c8724a46 | |||
| 5f0ac92335 | |||
| c8e707ddd7 | |||
| 48764f7801 | |||
| f7d22b4de3 | |||
| f91af5453c | |||
| c16d49acd0 | |||
| 87383bcc10 | |||
| 28192c181a | |||
| d7f2c3606b | |||
| 444ebbe95b | |||
| 5ecebcbc78 | |||
| 3a663bd7c4 | |||
| 9a782276a4 | |||
| f86dce9db1 | |||
| 37ac7c0377 | |||
| 2448ba2a95 | |||
| 75de04b6f8 | |||
| 8ecbfdf080 | |||
| f9c9851ef3 | |||
| 708f8bd4ab | |||
| c21722cd10 | |||
| db3889ceff | |||
| 3be7ae350e | |||
| 2a6813f2e7 | |||
| 842bc1ba70 | |||
| a1944a19a2 | |||
| c2d7a65cfd | |||
| cf84a0dc1c | |||
| 5fec019715 | |||
| c7bfd7cf83 | |||
| 1235106ac0 | |||
| 5e790014c1 | |||
| a9c89540ac | |||
| 1fc02c6b1d | |||
| f54edbf0d3 | |||
| 7274eca56c | |||
| e953c2b4ff | |||
| cf076474d2 | |||
| 4c7a97e890 | |||
| 10fe2cd1ab | |||
| b81ee48320 | |||
| e043cadb7c | |||
| 233fd40984 | |||
| 67c04d598f | |||
| f1dde3d84e | |||
| f8eb1b16ce | |||
| 119d6d4a1c | |||
| 8682a33fcb | |||
| 34da3c9fd5 | |||
| 0bacd6fbed | |||
| 98d4cea748 | |||
| a872178185 | |||
| 027b5105ac | |||
| d18e3fd6a5 | |||
| ae533e1b16 | |||
| 4f6d05b115 | |||
| 1e39e5f9af | |||
| c1f8fc6348 | |||
| f1dcc889ec | |||
| 1669a1fb2d | |||
| 5fd646dc67 | |||
| ac2a6d72a3 | |||
| 8d3cfd51a8 | |||
| 35a151c9b0 | |||
| aa0ef9b10c | |||
| cc3da5b51c | |||
| 83a1b490ea | |||
| 12b9ac21c4 | |||
| 5190a31109 | |||
| 192d43569b | |||
| aa5cfdfb3c | |||
| 519d96871f | |||
| 9c61f94492 | |||
| dd5a6bd9a4 | |||
| 37ca90b823 | |||
| 964d83df51 | |||
| b16c15342a | |||
| e636c5ec72 | |||
| 1654aaa24e | |||
| 4797a93e7b | |||
| 41d3f814ba | |||
| 5aa6cc3b03 | |||
| 2cdc3c3778 | |||
| f30144473d | |||
| 7a6121fbbf | |||
| 538977752f | |||
| 2d346be3fb | |||
| 405e8b2a53 | |||
| 9ca897dae2 | |||
| 683ab3be1d | |||
| aa4edd99cf | |||
| a87b1eea96 | |||
| 3c1395a626 | |||
| 80812e471a | |||
| edd622e5ac | |||
| 4db9b44b75 | |||
| c6a1c3dd92 | |||
| 7aacfe029e | |||
| 1361bfe530 | |||
| b92f05140b | |||
| 95d44a6109 | |||
| c7f63a348f | |||
| f1ad358bff | |||
| cfa63b8a4c | |||
| 41be013bc6 | |||
| 1e00c5139b | |||
| b3de839dee | |||
| 18234ebeee | |||
| 92207dde6a | |||
| 7343ddf980 | |||
| 434680c817 | |||
| b28164d7f8 |
@@ -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' },
|
||||
),
|
||||
]
|
||||
@@ -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
|
||||
@@ -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}
|
||||
@@ -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
|
||||
@@ -0,0 +1,275 @@
|
||||
# Copyright 2003-2019 Joaquín M López Muñoz.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/multi_index for library home page.
|
||||
|
||||
sudo: false
|
||||
|
||||
language: cpp
|
||||
|
||||
os: linux
|
||||
|
||||
dist: trusty
|
||||
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- master
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
exclude: # workaround for https://github.com/travis-ci/travis-ci/issues/4681
|
||||
- env: BOGUS_JOB=true
|
||||
include:
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
|
||||
- os: linux
|
||||
compiler: g++-4.4
|
||||
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.4
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-4.6
|
||||
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-4.7
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-4.8
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-4.9
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-5
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-6
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-8
|
||||
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-7
|
||||
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
|
||||
- os: linux
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.3
|
||||
- os: linux
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.4
|
||||
- os: linux
|
||||
compiler: clang++-3.5
|
||||
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.5
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.5
|
||||
- os: linux
|
||||
compiler: clang++-3.6
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.6
|
||||
- os: linux
|
||||
compiler: clang++-3.7
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
- os: linux
|
||||
compiler: clang++-3.8
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
- os: linux
|
||||
compiler: clang++-3.9
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.9
|
||||
- os: linux
|
||||
compiler: clang++-4.0
|
||||
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-4.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- os: linux
|
||||
compiler: clang++-5.0
|
||||
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-5.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
- os: linux
|
||||
compiler: clang++-6.0
|
||||
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-6.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-6.0
|
||||
- os: linux
|
||||
compiler: clang++-7
|
||||
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-7
|
||||
- os: linux
|
||||
compiler: clang++-7
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-7
|
||||
- libstdc++-5-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-7
|
||||
- os: linux
|
||||
compiler: clang++-libc++
|
||||
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
- os: linux
|
||||
compiler: clang++-libc++
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init
|
||||
- git rm --ignore-unmatch libs/multi_index/
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
- mkdir libs/multi_index
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/multi_index
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
- ./b2 libs/multi_index/test toolset=$TOOLSET cxxstd=$CXXSTD
|
||||
@@ -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()
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Boost.MultiIndex examples and tests Jamfile
|
||||
#
|
||||
# Copyright 2003-2004 Joaquín M López Muñoz.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/multi_index for library home page.
|
||||
|
||||
subproject libs/multi_index ;
|
||||
|
||||
# please order by name to ease maintenance
|
||||
|
||||
subinclude libs/multi_index/example ;
|
||||
subinclude libs/multi_index/test ;
|
||||
subinclude libs/multi_index/perf ;
|
||||
@@ -0,0 +1,48 @@
|
||||
# Boost Multi-index Containers Library
|
||||
|
||||
[](https://github.com/boostorg/multi_index/tree/master) [](https://github.com/boostorg/multi_index/actions/workflows/ci.yml) [](https://drone.cpp.al/boostorg/multi_index) [](https://pdimov.github.io/boostdep-report/master/multi_index.html) [](https://www.boost.org/doc/libs/master/libs/multi_index) [](https://regression.boost.org/master/developer/multi_index.html)<br/>
|
||||
[](https://github.com/boostorg/multi_index/tree/develop) [](https://github.com/boostorg/multi_index/actions/workflows/ci.yml) [](https://drone.cpp.al/boostorg/multi_index) [](https://pdimov.github.io/boostdep-report/develop/multi_index.html) [](https://www.boost.org/doc/libs/develop/libs/multi_index) [](https://regression.boost.org/develop/developer/multi_index.html)<br/>
|
||||
[](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 you’re 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).
|
||||
@@ -0,0 +1,37 @@
|
||||
# Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/multi_index for library home page.
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-14.0
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1
|
||||
CXXSTD: 14,17
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone -b %APPVEYOR_REPO_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init
|
||||
- git rm --ignore-unmatch libs/multi_index/
|
||||
- bootstrap
|
||||
- b2 headers
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\multi_index\
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- b2 address-model=32 libs/multi_index/test toolset=%TOOLSET% %CXXSTD%
|
||||
@@ -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
|
||||
;
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Acknowledgements</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<link rel="start" href="index.html">
|
||||
<link rel="prev" href="release_notes.html">
|
||||
<link rel="up" href="index.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -94,7 +97,7 @@ purpose. It is provided "as is" without express or implied warranty.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<span style="float:right;"><img src="lopez.jpg" width="160" height="120"></span>
|
||||
<span style="float:right;margin-left:10px"><img src="lopez.jpg" width="160" height="120"></span>
|
||||
I would like to dedicate this piece of work to Rosa Bernárdez, my very first
|
||||
C++ teacher, for her unconditional support in many endeavors of which programming is
|
||||
by no means the most important. In memory of my cat López (2001-2003): he
|
||||
@@ -118,6 +121,64 @@ capabilities are built. Toon Knapen helped adjust the library for VisualAge 6.0.
|
||||
Markus Schöpflin provided a Jamfile tweak for GCC under Tru64 UNIX.
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_34">Boost 1.34 release</a></h2>
|
||||
|
||||
<p>
|
||||
<span style="float:left;margin-right:10px"><img src="hector.jpg" width="150" height="198"></span>
|
||||
Thanks go to Pavel Voženílek for his useful comments and suggestions
|
||||
during the development of this release, and to Rosa Bernárdez for reviewing
|
||||
the new material in the documentation.
|
||||
Alo Sarv suggested a notational improvement in the specification of
|
||||
partial searches with composite keys.
|
||||
Maxim Yegorushkin proposed a valuable
|
||||
<a href="tutorial/indices.html#ordered_node_compression">spatial optimization</a>
|
||||
for ordered indices and provided figures of its impact on performance
|
||||
for containers with large numbers of elements.
|
||||
Caleb Epstein performed the tests under MSVC++ 8.0 described in the
|
||||
performance section. The following people have reported bugs and problems with
|
||||
previous versions and prereleases of the library: Alexei Alexandrov,
|
||||
Matías Capeletto, John Eddy, Martin Eigel, Guillaume Lazzara,
|
||||
Felipe Magno de Almeida, Julien Pervillé, Hubert Schmid, Toby Smith.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
New member in the family! Thanks to Héctor for his patience during
|
||||
long development sessions and his occasional contributions to the source
|
||||
codebase.
|
||||
<br style="clear:all;">
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_35">Boost 1.35 release</a></h2>
|
||||
|
||||
<p>
|
||||
<a href="tutorial/key_extraction.html#global_fun"><code>global_fun</code></a>
|
||||
was included after a proposal by Markus Werle. Bruno Martínez Aguerre
|
||||
suggested the inclusion of
|
||||
<a href="tutorial/indices.html#iterator_to"><code>iterator_to</code></a>. The
|
||||
rollback versions of <code>modify</code> and <code>modify_key</code> arose
|
||||
from discussions with Matías Capeletto. Steven Watanabe spotted an
|
||||
include guard bug present from the first release of the library.
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_36">Boost 1.36 release</a></h2>
|
||||
|
||||
<p>
|
||||
Thanks to Amit Jain for reporting a problem with allocator management.
|
||||
Michael Fawcett proposed the addition of an allocator constructor to
|
||||
<code>multi_index_container</code>.
|
||||
A report from Zachary Zhou has led to
|
||||
<a href="release_notes.html#stable_update">enhancing the behavior of
|
||||
hashed indices update functions</a> so that they meet some intuitive expectations.
|
||||
Grzegorz Jakacki spotted some internal dead code.
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_56">Boost 1.56 release</a></h2>
|
||||
|
||||
<p>
|
||||
Stephen Kelly has contributed the removal of workaround code for old compilers
|
||||
no longer supported.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="release_notes.html"><img src="prev.gif" alt="release notes" border="0"><br>
|
||||
@@ -131,9 +192,9 @@ Index
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 11th 2005</p>
|
||||
<p>Revised October 9th 2013</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2013 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -1,941 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Compiler specifics</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Compiler specifics</h1>
|
||||
|
||||
<div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="performance.html"><img src="next.gif" alt="performance" border="0"><br>
|
||||
Performance
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex has been tried in different compilers, with
|
||||
various degrees of success. We list the limitations encountered,
|
||||
along with suitable workarounds when available.
|
||||
</p>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#bcb_64">Borland C++ Builder 6.4</a></li>
|
||||
<li><a href="#comeau_433_win_vc7_71">Comeau C/C++ 4.3.3 for Windows (VC++ 7.0/7.1 backend)</a></li>
|
||||
<li><a href="#compaq_65">Compaq C++ 6.5-042 for Tru64 UNIX</a></li>
|
||||
<li>
|
||||
<a href="#gcc_32">GNU GCC 3.2 and later</a>
|
||||
<ul>
|
||||
<li><a href="#gcc_tru64">GNU GCC for Tru64 UNIX</a></li>
|
||||
<li><a href="#gcc_4_darwin">Darwin GCC 4.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#acc_60">HP aC++ A.06.00 for HP-UX</a></li>
|
||||
<li><a href="#va_60">IBM VisualAge C++ V6.0 for AIX</a></li>
|
||||
<li><a href="#intel_71_8x_lin">Intel C++ Compiler for Linux 7.1/8.0/8.1</a></li>
|
||||
<li><a href="#intel_em64t_81_lin">Intel C++ Compiler Extended Memory 64 Technology 8.1 for Linux</a></li>
|
||||
<li><a href="#intel_7x_win">Intel C++ Compiler for Windows 32-bit 7.0/7.1</a></li>
|
||||
<li><a href="#intel_71_win_stlport_453">Intel C++ Compiler for Windows 32-bit 7.1 + STLport 4.5.3</a></li>
|
||||
<li><a href="#intel_8x_9x_win">Intel C++ Compiler for Windows 32-bit 8.0/8.1/9.0</a></li>
|
||||
<li><a href="#cw_83_9x">Metrowerks CodeWarrior 8.3 and later</a></li>
|
||||
<li><a href="#msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a></li>
|
||||
<li><a href="#msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5 + STLport 4.5.3</a></li>
|
||||
<li><a href="#msvc_70">Microsoft Visual C++ 7.0</a></li>
|
||||
<li><a href="#msvc_71">Microsoft Visual C++ 7.1</a></li>
|
||||
<li><a href="#msvc_80">Microsoft Visual C++ 8.0</a></li>
|
||||
<li><a href="#portability">Portability techniques</a>
|
||||
<ul>
|
||||
<li><a href="#member_offset">Use of <code>member_offset</code></a></li>
|
||||
<li><a href="#mem_fun_explicit">Use of <code>const_mem_fun_explicit</code> and
|
||||
<code>mem_fun_explicit</code></a></li>
|
||||
<li><a href="#composite_key_no_pts"><code>composite_key</code> in compilers
|
||||
without partial template specialization</a></li>
|
||||
<li><a href="#symbol_reduction">Reduction of symbol name lengths</a>
|
||||
<ul>
|
||||
<li><a href="#argument_limitation">Limitation of maximum number of arguments</a></li>
|
||||
<li><a href="#type_hiding">Type hiding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="bcb_64">Borland C++ Builder 6.4</a></h2>
|
||||
|
||||
<p>
|
||||
Currently, Boost.MultiIndex cannot be used with BCB 6.4. The
|
||||
number of problems encountered during the tests makes it unlikely that
|
||||
future versions of the library can be made to work under
|
||||
this compiler.
|
||||
</p>
|
||||
|
||||
<h2><a name="comeau_433_win_vc7_71">Comeau C/C++ 4.3.3 for Windows (VC++ 7.0/7.1 backend)</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler. The library fails to compile,
|
||||
however, when Microsoft Visual C++ 6.0 is used as the backend.
|
||||
</p>
|
||||
|
||||
<h2><a name="compaq_65">Compaq C++ 6.5-042 for Tru64 UNIX</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
</p>
|
||||
|
||||
<h2><a name="gcc_32">GNU GCC 3.2 and later</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with several versions of this compiler
|
||||
starting from 3.2. The following versions have been explicitly tested:
|
||||
<ul>
|
||||
<li>GCC 3.2 20020903 under Linux,</li>
|
||||
<li>GCC 3.2 20020927 (prerelease) under Cygwin 1.5.7,</li>
|
||||
<li>GCC 3.2.3 under Linux, (mingw special 20030504-1) under Win32,</li>
|
||||
<li>GCC 3.3 20030304 (Apple builds 1666 and 1671) under Mac OS,</li>
|
||||
<li>GCC 3.3.3 (cygwin special) under Cygwin 1.5.7,</li>
|
||||
<li>GCC 3.3.5 under Linux,</li>
|
||||
<li>GCC 3.3.6 under Linux and Tru64 (see <a href="#gcc_tru64">below</a>),</li>
|
||||
<li>GCC 3.4.2 (mingw-special) under Win32,</li>
|
||||
<li>GCC 3.4.3 under Linux, Solaris and Tru64 (see <a href="#gcc_tru64">below</a>),</li>
|
||||
<li>GCC 3.4.4 (cygming special) under Cygwin, under Linux,
|
||||
under Tru64 (see <a href="#gcc_tru64">below</a>), (mingw special) under Win32,</li>
|
||||
<li>GCC 4.0.0 20041026 (Apple build 4061) under Mac OS
|
||||
(see <a href="#gcc_4_darwin">below</a>),</li>
|
||||
<li>GCC 4.0.0 under Linux, (Apple build 5026) under Mac OS,</li>
|
||||
<li>GCC 4.0.1 under Linux.</li>
|
||||
</ul>
|
||||
Boost.MultiIndex does not work with versions 3.1 and prior of GCC.
|
||||
</p>
|
||||
|
||||
<h3><a name="gcc_tru64">GNU GCC for Tru64 UNIX</a></h3>
|
||||
|
||||
<p>
|
||||
On this platform, GCC is not able to handle debug symbol names whose length
|
||||
exceeds 32,768 bytes, resulting in the error <code>mips-tfile, ... string
|
||||
too big</code>. You may encounter this issue with heavily templatized
|
||||
code like Boost.MultiIndex, which typically produces long symbol names. The problem
|
||||
can be overcome by omitting the compiler option <code>-g</code> (generate debugging
|
||||
information.) Alternatively, consult the section on
|
||||
<a href="#symbol_reduction">reduction of symbol name lengths</a> for various
|
||||
applicable workarounds.
|
||||
</p>
|
||||
|
||||
<h3><a name="gcc_4_darwin">Darwin GCC 4.0</a></h3>
|
||||
|
||||
<p>
|
||||
Build 4061 of GCC 4.0, shipped with Darwin 8.2 and prior (Mac OS X 10.4.2 and
|
||||
prior), corresponds to a prerelease version of GNU GCC 4.0.0 which introduces
|
||||
a <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17435">regression bug</a>
|
||||
related to binding of references to temporary objects. This bug precludes the
|
||||
usage of Boost.MultiIndex
|
||||
<a href="advanced_topics.html#invariant_check">invariant-checking mode</a>; other
|
||||
than this, Boost.MultiIndex works correctly.
|
||||
The bug is corrected in GCC 4.0 Apple build 5026, which is in sync with the official
|
||||
release of GNU GCC 4.0.0, so the invariant-checking mode is available from this
|
||||
upgrade.
|
||||
</p>
|
||||
|
||||
<h2><a name="acc_60">HP aC++ A.06.00 for HP-UX</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
</p>
|
||||
|
||||
<h2><a name="va_60">IBM VisualAge C++ V6.0 for AIX</a></h2>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
|
||||
refer to the section on
|
||||
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
|
||||
<code>member_offset</code> causes the compiler to emit warnings about the
|
||||
use of <code>offsetof</code> with non-POD types: these warnings can be suppressed
|
||||
by setting the compiler option <code>-qsuppress=1540-1281</code>, or, alternatively,
|
||||
by inserting the following preprocessor directive:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#pragma</span> <span class=identifier>info</span><span class=special>(</span><span class=identifier>nolan</span><span class=special>)</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
This latter pragma, however, may also eliminate other warnings not related
|
||||
to the use of <code>offsetof</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
Serialization capabilities are not available as Boost.Serialization is not
|
||||
supported on this platform.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_71_8x_lin">Intel C++ Compiler for Linux 7.1/8.0/8.1</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with these compilers.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_em64t_81_lin">Intel C++ Compiler Extended Memory 64 Technology 8.1
|
||||
for Linux</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_7x_win">Intel C++ Compiler for Windows 32-bit 7.0/7.1</a></h2>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
|
||||
refer to the section on
|
||||
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
When used on top of MSVC++ 7.0 or prior, argument dependent lookup is
|
||||
disabled by default. This will cause problems with many Boost libraries,
|
||||
and in particular with the serialization part of Boost.MultiIndex.
|
||||
Argument dependent lookup is enabled by adding
|
||||
<code>/Qoption,c,--arg_dep_lookup</code> to the project options.
|
||||
</p>
|
||||
|
||||
<h2><a name="#intel_71_win_stlport_453">
|
||||
Intel C++ Compiler for Windows 32-bit 7.1 + STLport 4.5.3</a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex works for this configuration. The same limitations apply as
|
||||
in Intel C++ 7.1 with its original Dinkumware standard library. STLport 4.6.2 has
|
||||
also been confirmed to work correctly.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_8x_9x_win">Intel C++ Compiler for Windows 32-bit 8.0/8.1/9.0</a></h2>
|
||||
|
||||
<p>
|
||||
When used on top of MSVC++ 7.0 or prior, argument dependent lookup is
|
||||
disabled by default. This will cause problems with many Boost libraries,
|
||||
and in particular with the serialization part of Boost.MultiIndex.
|
||||
Argument dependent lookup is enabled by adding
|
||||
<code>/Qoption,c,--arg_dep_lookup</code> to the project options.
|
||||
Other than this, Boost.MultiIndex works without problems.
|
||||
</p>
|
||||
|
||||
<h2><a name="cw_83_9x">Metrowerks CodeWarrior 8.3 and later</a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex works correctly with versions of this compiler from 8.3 to
|
||||
9.5, under the two operating systems tested: Mac OS and Windows.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a></h2>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
|
||||
refer to the section on
|
||||
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#const_mem_fun"><code>const_mem_fun</code></a> and
|
||||
<a href="reference/key_extraction.html#mem_fun"><code>mem_fun</code></a>
|
||||
not supported, refer to the section on
|
||||
<a href="#mem_fun_explicit">use of <code>const_mem_fun_explicit</code> and
|
||||
<code>mem_fun_explicit</code></a> for workarounds.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
No support for <a href="reference/multi_index_container.html#index_retrieval">index retrieval</a>
|
||||
and <a href="reference/multi_index_container.html#projection">projection</a>
|
||||
nested types and member functions:
|
||||
<ul>
|
||||
<li><code>nth_index</code>,</li>
|
||||
<li><code>index</code>,</li>
|
||||
<li><code>nth_index_iterator</code>,</li>
|
||||
<li><code>nth_index_const_iterator</code>,</li>
|
||||
<li><code>index_iterator</code>,</li>
|
||||
<li><code>index_const_iterator</code>,</li>
|
||||
<li><code>get</code>,</li>
|
||||
<li><code>project</code>.</li>
|
||||
</ul>
|
||||
You can use instead their global equivalents. Also, this compiler does not
|
||||
implement argument dependent lookup, so you might need to explicitly qualify
|
||||
these global names with <code>::boost::multi_index</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
<code>boost::multi_index::multi_index_container</code> is imported to
|
||||
<code>namespace boost</code> by means of a <code>using</code> declaration.
|
||||
MSVC++ 6.0, however, does not properly handle this import. So, instead of
|
||||
writing:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
use the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
or else resort to a directive <code>using namespace boost::multi_index</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
The lack of partial template specialization support in MSVC++ 6.0
|
||||
results in some inconveniences when using <code>composite_key</code> that
|
||||
can be remedied as explained in
|
||||
<a href="#composite_key_no_pts">"<code>composite_key</code>
|
||||
in compilers without partial template specialization"</a>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
MSVC++ 6.0 presents serious limitations for the maximum length of
|
||||
symbol names generated by the compiler, which might result in the
|
||||
linker error
|
||||
<code><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/lnk1179.asp">LNK1179</a>:
|
||||
invalid or corrupt file: duplicate comdat
|
||||
comdat</code>. To overcome this problem, consult the section on
|
||||
<a href="#symbol_reduction">reduction of symbol name lengths</a> for various
|
||||
applicable workarounds.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
Under some circumstances, the compiler emits the error
|
||||
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/C2587.asp">
|
||||
<code>C2587</code></a><code>: '_U' : illegal use of local variable as
|
||||
default parameter</code>, inside the MSVC internal header
|
||||
<code><xlocnum></code>.
|
||||
This problem is a recurrent bug of the compiler, and has been reported in
|
||||
other unrelated libraries, like the
|
||||
<a href="../../../libs/graph/doc/table_of_contents.html">Boost Graph Library</a>,
|
||||
<a href="../../../libs/multi_array/doc/index.html">Boost.MultiArray</a>,
|
||||
<a href="../../../libs/regex/doc/index.html">Boost.Regex</a>,
|
||||
<a href="http://www.cgal.org/">CGAL</a> and
|
||||
<a href="http://www.mysql.com/downloads/api-mysql++.html">MySQL++</a>.
|
||||
The error is triggered, though not in a systematic manner, by the use
|
||||
of <code>multi_index_container</code> iterator constructor. Two workarounds exist:
|
||||
the first consists of avoiding this constructor and replacing
|
||||
code like:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><...></span> <span class=identifier>s</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
with equivalent operations:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><...></span> <span class=identifier>s</span><span class=special>;</span>
|
||||
<span class=identifier>s</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The second workaround has not been confirmed by the author, but it is given
|
||||
on the Internet in connection with this error appearing in other libraries.
|
||||
Replace line 84 of <code><xlocnum></code>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span> <span class=keyword>virtual</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
with the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<b>Warning</b>: it is not known whether this
|
||||
replacement can result in unexpected side effects in code implicitly
|
||||
using <code><xlocnum></code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
In general, the extensive use of templates by Boost.MultiIndex puts this compiler
|
||||
under severe stress, so that several internal limitations may be reached.
|
||||
The following measures can help alleviate these problems:
|
||||
<ul>
|
||||
<li>Set the compiler option <code>/Zm</code> (Specify Memory Allocation Limit)
|
||||
to increase the amount of memory available for compilation. Usual values for
|
||||
this option range from 300 to 800.</li>
|
||||
<li>If in debug mode, try switching from <code>/ZI</code> (Program Database for
|
||||
Edit and Continue) to a less demanding type of debugging information
|
||||
(<code>/Zi</code>, <code>/Z7</code> or <code>/Zd</code>.)</li>
|
||||
<li>Play with the precompiled headers options. Usually, turning this feature
|
||||
off yields the best results.</li>
|
||||
<li>If the compiler emits the error
|
||||
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/c1055.asp">
|
||||
<code>C1055</code></a><code>: compiler limit : out of keys</code>, try
|
||||
disabling the option <code>/Gm</code> (Enable Minimal Rebuild.) In these
|
||||
cases, it is also beneficial to split the project into smaller
|
||||
subprojects.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5
|
||||
+ STLport 4.5.3</a>
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex works for this configuration. The same limitations apply as
|
||||
in MSVC++ 6.0 with its original Dinkumware standard library. STLport 4.6.2 has
|
||||
also been confirmed to work correctly.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
It is not possible to use the serialization capabilities of Boost.MultiIndex
|
||||
along with the dynamic version of STLport, as some linking errors result.
|
||||
Use instead the static version of STLport. This bug is reportedly fixed in
|
||||
STLport 5.0 (in beta stage as of this writing.)
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_70">Microsoft Visual C++ 7.0</a></h2>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
|
||||
refer to the section on
|
||||
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
No support for <a href="reference/multi_index_container.html#index_retrieval">index retrieval</a>
|
||||
and <a href="reference/multi_index_container.html#projection">projection</a>
|
||||
nested types and member functions:
|
||||
<ul>
|
||||
<li><code>nth_index</code>,</li>
|
||||
<li><code>index</code>,</li>
|
||||
<li><code>nth_index_iterator</code>,</li>
|
||||
<li><code>nth_index_const_iterator</code>,</li>
|
||||
<li><code>index_iterator</code>,</li>
|
||||
<li><code>index_const_iterator</code>,</li>
|
||||
<li><code>get</code>,</li>
|
||||
<li><code>project</code>.</li>
|
||||
</ul>
|
||||
You can use instead their global equivalents. Also, this compiler does not
|
||||
implement argument dependent lookup, so you might need to explicitly qualify
|
||||
these global names with <code>::boost::multi_index</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
<code>boost::multi_index::multi_index_container</code> is imported to
|
||||
<code>namespace boost</code> by means of a <code>using</code> declaration.
|
||||
MSVC++ 7.0, however, does not properly handle this import. So, instead of
|
||||
writing:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
use the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
or else resort to a directive <code>using namespace boost::multi_index</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
The lack of partial template specialization support in MSVC++ 7.0
|
||||
results in some inconveniences when using <code>composite_key</code> that
|
||||
can be remedied as explained in
|
||||
<a href="#composite_key_no_pts">"<code>composite_key</code>
|
||||
in compilers without partial template specialization"</a>.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_71">Microsoft Visual C++ 7.1</a></h2>
|
||||
|
||||
<p>
|
||||
Problems have been reported when compiling the library with the <code>/Gm</code>
|
||||
option (Enable Minimal Rebuild.) Seemingly, this is due to an
|
||||
internal defect of the compiler (see for instance
|
||||
<a href="http://lists.boost.org/MailArchives/boost-users/msg05988.php">
|
||||
this mention of a similar issue</a> in the Boost Users mailing list.)
|
||||
If <code>/Gm</code> is turned off, Boost.MultiIndex compiles and runs
|
||||
without further problems.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_80">Microsoft Visual C++ 8.0</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler. The Beta 2 version of
|
||||
this product was used for the testing.
|
||||
</p>
|
||||
|
||||
<h2><a name="portability">Portability techniques</a></h2>
|
||||
|
||||
<h3><a name="member_offset">Use of <code>member_offset</code></a></h3>
|
||||
|
||||
<p>
|
||||
The <code>member</code> key extractor poses some problems in compilers
|
||||
that do not properly support pointers to members as non-type
|
||||
template arguments, as indicated by the
|
||||
<a href="../../../libs/config/config.htm">Boost Configuration Library</a>
|
||||
defect macro <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code>.
|
||||
The following compilers have been confirmed not
|
||||
to work correctly with <code>member</code>:
|
||||
<ul>
|
||||
<li>MSVC++ 6.0/7.0,</li>
|
||||
<li>Intel C++ 7.0/7.1 for Windows,</li>
|
||||
<li>VisualAge 6.0 for AIX.</li>
|
||||
</ul>
|
||||
This program can help determine if your compiler
|
||||
properly supports pointers to members as non-type template parameters:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>iostream</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>pair</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>y</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>pair</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>x_</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>y_</span><span class=special>):</span><span class=identifier>x</span><span class=special>(</span><span class=identifier>x_</span><span class=special>),</span><span class=identifier>y</span><span class=special>(</span><span class=identifier>y_</span><span class=special>){}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>pair</span><span class=special>::*</span> <span class=identifier>PtrToPairMember</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>foo</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>bar</span><span class=special>(</span><span class=identifier>pair</span><span class=special>&</span> <span class=identifier>p</span><span class=special>){</span><span class=keyword>return</span> <span class=identifier>p</span><span class=special>.*</span><span class=identifier>PtrToPairMember</span><span class=special>;}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>pair</span> <span class=identifier>p</span><span class=special>(</span><span class=number>0</span><span class=special>,</span><span class=number>1</span><span class=special>);</span>
|
||||
<span class=identifier>foo</span><span class=special><&</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>x</span><span class=special>></span> <span class=identifier>fx</span><span class=special>;</span>
|
||||
<span class=identifier>foo</span><span class=special><&</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>y</span><span class=special>></span> <span class=identifier>fy</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>if</span><span class=special>(</span><span class=identifier>fx</span><span class=special>.</span><span class=identifier>bar</span><span class=special>(</span><span class=identifier>p</span><span class=special>)!=</span><span class=number>0</span><span class=special>||</span><span class=identifier>fy</span><span class=special>.</span><span class=identifier>bar</span><span class=special>(</span><span class=identifier>p</span><span class=special>)!=</span><span class=number>1</span><span class=special>)</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special><<</span><span class=string>"KO"</span><span class=special><<</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span>
|
||||
<span class=keyword>else</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special><<</span><span class=string>"OK"</span><span class=special><<</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>return</span> <span class=number>0</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
If you find a compiler that does not pass the test, and for which
|
||||
<code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code> is <i>not</i> defined,
|
||||
please report to the Boost developers mailing list.
|
||||
</p>
|
||||
<p>To overcome this defect, a replacement utility
|
||||
<a href="reference/key_extraction.html#member_offset"><code>member_offset</code></a>
|
||||
has been provided that does the work of <code>member</code> at the
|
||||
expense of less convenient notation and the possibility of
|
||||
non-conformance with the standard. Please consult
|
||||
the reference for further information on <code>member_offset</code>.
|
||||
As an example of use, given the class
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>class</span> <span class=identifier>A</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
the instantiation <code>member<A,int,&A::x></code> can be simulated then
|
||||
as <code>member_offset<A,int,offsetof(A,x)></code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For those writing portable code, Boost.MultiIndex provides the ternary macro
|
||||
<a href="reference/key_extraction.html#boost_multi_index_member"><code>BOOST_MULTI_INDEX_MEMBER</code></a>.
|
||||
Continuing with the example above, the
|
||||
expression
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>BOOST_MULTI_INDEX_MEMBER</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>x</span><span class=special>)</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
expands by default to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>x</span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
or alternatively to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>member_offset</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>offsetof</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=identifier>x</span><span class=special>)></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
if <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code> is defined.
|
||||
</p>
|
||||
|
||||
<h3><a name="mem_fun_explicit">Use of <code>const_mem_fun_explicit</code> and
|
||||
<code>mem_fun_explicit</code></a></h3>
|
||||
|
||||
<p>
|
||||
MSVC++ 6.0 has problems with <code>const</code> member functions as non-type
|
||||
template parameters, and thus does not accept the <code>const_mem_fun</code>
|
||||
key extractor. A simple workaround, fortunately, has been found, consisting
|
||||
in specifying the <i>type</i> of these pointers as an additional template
|
||||
parameter. The alternative
|
||||
<a href="reference/key_extraction.html#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>
|
||||
extractor adopts this solution; for instance, given the type
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>A</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>f</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
the extractor <code>const_mem_fun<A,int,&A::f></code> can be replaced by
|
||||
<code>const_mem_fun_explicit<A,int,int (A::*)()const,&A::f></code>. A similar
|
||||
<code>mem_fun_explicit</code> class template is provided for non-constant
|
||||
member functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you are writing cross-platform code, the selection of either key extractor
|
||||
is transparently handled by the macro
|
||||
<a href="reference/key_extraction.html#boost_multi_index_const_mem_fun"><code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code></a>,
|
||||
so that
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>f</span><span class=special>)</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
expands by default to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>const_mem_fun</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
but resolves to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>const_mem_fun_explicit</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=keyword>int</span> <span class=special>(</span><span class=identifier>A</span><span class=special>::*)()</span><span class=keyword>const</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
in MSVC++ 6.0. Non-<code>const</code> member functions are covered by
|
||||
<a href="reference/key_extraction.html#mem_fun_explicit"><code>mem_fun_explicit</code></a>
|
||||
and the macro
|
||||
<a href="reference/key_extraction.html#boost_multi_index_mem_fun"><code>BOOST_MULTI_INDEX_MEM_FUN</code></a>.
|
||||
</p>
|
||||
|
||||
<h3><a name="composite_key_no_pts"><code>composite_key</code> in compilers
|
||||
without partial template specialization</a></h3>
|
||||
|
||||
<p>
|
||||
When using <code>composite_key</code>s, lookup is performed by passing
|
||||
tuples of values: this ability is achieved by suitably specializing
|
||||
the class templates <code>std::equal_to</code>, <code>std::less</code>,
|
||||
<code>std::greater</code> and <code>boost::hash</code> for
|
||||
<a href="reference/key_extraction.html#composite_key_result">
|
||||
<code>composite_key_result</code></a> instantiations so that they
|
||||
provide the appropriate overloads accepting tuples --and in the case
|
||||
of <code>std::less</code> and <code>std::greater</code>, also partial
|
||||
tuples where only the first components are specified.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In those compilers that do not support partial template specialization,
|
||||
these specializations cannot be provided, and so
|
||||
tuple-based lookup is not available by default. In this case,
|
||||
<code>multi_index_container</code> instantiations using composite keys
|
||||
will work as expected, both for ordered and hashed indices,
|
||||
except that lookup operations will not accept tuples as an argument.
|
||||
For ordered indices, the most obvious workaround
|
||||
to this deficiency involves explicitly specifying the comparison
|
||||
predicate with
|
||||
<a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>;
|
||||
in the case of hashed indices we can use the analogous
|
||||
<a href="reference/key_extraction.html#composite_key_equal_to"><code>composite_key_equal_to</code></a>
|
||||
and
|
||||
<a href="reference/key_extraction.html#composite_key_hash"><code>composite_key_hash</code></a>.
|
||||
This substitution is tedious as the elementary components for all the constituent key extractors must
|
||||
be explicitly typed. For this reason, Boost.MultiIndex provides the following replacement
|
||||
class templates
|
||||
<ul>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_equal_to">
|
||||
<code>composite_key_result_equal_to</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_less">
|
||||
<code>composite_key_result_less</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_greater">
|
||||
<code>composite_key_result_greater</code></a> and</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_hash">
|
||||
<code>composite_key_result_hash</code></a>,</li>
|
||||
</ul>
|
||||
that act as the missing specializations of <code>std::equal_to</code>, <code>std::less</code>,
|
||||
<code>std::greater</code> and <code>boost::hash</code> for <code>composite_key_result</code>s.
|
||||
They can be used as follows:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>composite_key</span><span class=special><</span>
|
||||
<span class=identifier>phonebook_entry</span><span class=special>,</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>family_name</span><span class=special>>,</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>given_name</span><span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>ckey_t</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>phonebook_entry</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span>
|
||||
<span class=identifier>ckey_t</span><span class=special>,</span>
|
||||
<span class=comment>// composite_key_result_less plays the role of
|
||||
// std::less<ckey_t::result_type></span>
|
||||
<span class=identifier>composite_key_result_less</span><span class=special><</span><span class=identifier>ckey_t</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>phone_number</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>phonebook</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="symbol_reduction">Reduction of symbol name lengths</a></h3>
|
||||
|
||||
<p>
|
||||
The types generated on the instantiations of <code>multi_index_container</code>s
|
||||
typically produce very long symbol names, sometimes beyond the internal limits
|
||||
of some compilers. There are several techniques to shorten generated symbol
|
||||
names: these techniques have also the beneficial side effect that resulting error
|
||||
messages are more readable.
|
||||
</p>
|
||||
|
||||
<h4><a name="argument_limitation">Limitation of maximum number of arguments</a></h4>
|
||||
|
||||
<p>
|
||||
The class templates <a href="reference/indices.html#indexed_by"><code>indexed_by</code></a>,
|
||||
<a href="reference/indices.html#tag"><code>tag</code></a> and
|
||||
<a href="reference/key_extraction.html#composite_key"><code>composite_key</code></a>
|
||||
accept a variable number of arguments whose maximum number is limited by
|
||||
internal macros. Even non-used arguments contribute to the final types,
|
||||
so manually adjusting the corresponding macros can result in a modest reduction
|
||||
of symbol names.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<caption><b>Limiting maximum number of arguments of some class templates
|
||||
of Boost.MultiIndex.</b></caption>
|
||||
<tr>
|
||||
<th>class template</th>
|
||||
<th>limiting macro</th>
|
||||
<th>default value</th>
|
||||
<th>default value<br>(MSVC++ 6.0)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"> <code>indexed_by</code> </td>
|
||||
<td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE</code> </td>
|
||||
<td align="center">20</td>
|
||||
<td align="center">5</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td align="center"> <code>tag</code> </td>
|
||||
<td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_TAG_SIZE</code> </td>
|
||||
<td align="center">20</td>
|
||||
<td align="center">3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"> <code>composite_key</code> </td>
|
||||
<td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE</code> </td>
|
||||
<td align="center">10</td>
|
||||
<td align="center">5</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<h4><a name="type_hiding">Type hiding</a></h4>
|
||||
|
||||
<p>
|
||||
Consider a typical instantiation of <code>multi_index_container</code>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>employee_set</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Then, for instance, the type <code>employee_set::nth_type<0>::type</code>
|
||||
resolves to the following in GCC:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_index</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>nth_layer</span><span class=special><</span>
|
||||
<span class=number>1</span><span class=special>,</span> <span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_unique</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_non_unique</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span> <span class=special>&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_unique</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span> <span class=keyword>int</span><span class=special>,</span> <span class=special>&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>vector0</span><span class=special><</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_unique_tag</span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
It can be seen that a significant portion of the type name is contributed by
|
||||
the <code>indexed_by<...></code> part, which is nothing but an expanded
|
||||
version of the index specifier list provided in the definition of
|
||||
<code>employee_set</code>. We can prevent this very long name from appearing
|
||||
in the final type by encapsulating it into another, shorter-named construct:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// reducing symbol names through type hiding
|
||||
// type hide the index spexifier list within employee_set_indices</span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>employee_set_indices</span><span class=special>:</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>{};</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>employee_set_indices</span>
|
||||
<span class=special>></span> <span class=identifier>employee_set</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>employee_set_indices</code> works as a conventional <code>typedef</code>
|
||||
in all respects, save for a detail: its name does not explicitly
|
||||
include the information contained in the <code>indexed_by</code> instantiation.
|
||||
Applying this technique, <code>employee_set::nth_type<0>::type</code>
|
||||
now becomes:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_index</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>nth_layer</span><span class=special><</span>
|
||||
<span class=number>1</span><span class=special>,</span> <span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>employee_set_indices</span><span class=special>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>vector0</span><span class=special><</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_unique_tag</span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
which is considerably shorter than the original, and also more
|
||||
easily parsed by a human reader. Type hiding would not work if, instead of
|
||||
making <code>employee_set_indices</code> a derived <code>struct</code> of
|
||||
<code>indexed_by<...></code>, we had defined it as a <code>typedef</code>:
|
||||
<code>typedef</code>s are syntactic aliases and usually get expanded
|
||||
by the compiler before doing any further type handling.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Type hiding techniques can also be applied to <code>composite_key</code> intantiations,
|
||||
which often contribute a great deal to symbol name lengths.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="performance.html"><img src="next.gif" alt="performance" border="0"><br>
|
||||
Performance
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 26th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,6 +5,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Examples</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<link rel="start" href="index.html">
|
||||
<link rel="prev" href="performance.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="tests.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -27,7 +31,7 @@ Tests
|
||||
|
||||
<ul>
|
||||
<li><a href="#example1">Example 1: basic usage</a></li>
|
||||
<li><a href="#example2">Example 2: using member functions as keys</a></li>
|
||||
<li><a href="#example2">Example 2: using functions as keys</a></li>
|
||||
<li><a href="#example3">Example 3: constructing <code>multi_index_container</code>s
|
||||
with <code>ctor_args_list</code></a></li>
|
||||
<li><a href="#example4">Example 4: bidirectional map</a></li>
|
||||
@@ -36,6 +40,9 @@ Tests
|
||||
<li><a href="#example7">Example 7: composite keys</a></li>
|
||||
<li><a href="#example8">Example 8: hashed indices</a></li>
|
||||
<li><a href="#example9">Example 9: serialization and MRU lists</a></li>
|
||||
<li><a href="#example10">Example 10: random access indices</a></li>
|
||||
<li><a href="#example11">Example 11: index rearrangement</a></li>
|
||||
<li><a href="#example12">Example 12: using Boost.Interprocess allocators</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="example1">Example 1: basic usage</a></h2>
|
||||
@@ -49,23 +56,23 @@ Basic program showing the multi-indexing capabilities of Boost.MultiIndex
|
||||
with an admittedly boring set of <code>employee</code> records.
|
||||
</p>
|
||||
|
||||
<h2><a name="example2">Example 2: using member functions as keys</a></h2>
|
||||
<h2><a name="example2">Example 2: using functions as keys</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/memfun_key.cpp">source code</a>.
|
||||
See <a href="../example/fun_key.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Usually keys assigned to an index are based on a member variable of the
|
||||
element, but key extractors can be defined which take their value from
|
||||
a member function. This has some similarity with the concept of
|
||||
a member function or a global function. This has some similarity with the concept of
|
||||
<i>calculated keys</i> supported by some relational database engines.
|
||||
The example shows how to use the predefined <code>const_mem_fun</code>
|
||||
key extractor to deal with this situation.
|
||||
and <code>global_fun</code> key extractors to deal with this situation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Keys based on member functions usually will not be actual references,
|
||||
Keys based on functions usually will not be actual references,
|
||||
but rather the temporary values resulting from the invocation of the
|
||||
member function used. This implies that <code>modify_key</code> cannot be
|
||||
applied to this type of extractors, which is a perfectly logical
|
||||
@@ -82,7 +89,7 @@ See <a href="../example/non_default_ctor.cpp">source code</a>.
|
||||
<p>
|
||||
We show a practical example of usage of <code>multi_index_container::ctor_arg_list</code>,
|
||||
whose definition and purpose are explained in the
|
||||
<a href="advanced_topics.html#ctor_args_list">Advanced topics section</a>. The
|
||||
<a href="tutorial/creation.html#ctor_args_list">tutorial</a>. The
|
||||
program groups a sorted collection of numbers based on identification through
|
||||
modulo arithmetics, by which <code>x</code> and <code>y</code> are equivalent
|
||||
if <code>(x%n)==(y%n)</code>, for some fixed <code>n</code>.
|
||||
@@ -97,14 +104,20 @@ See <a href="../example/bimap.cpp">source code</a>.
|
||||
<p>
|
||||
This example shows how to construct a bidirectional map with
|
||||
<code>multi_index_container</code>. By a <i>bidirectional map</i> we mean
|
||||
a container of elements of <code>std::pair<const FromType,const ToType></code>
|
||||
such that no two elements exists with the same <code>first</code>
|
||||
<i>or</i> <code>second</code> value (<code>std::map</code> only
|
||||
guarantees uniqueness of the first member). Fast lookup is provided
|
||||
a container of <code>(const FromType,const ToType)</code> pairs
|
||||
such that no two elements exist with the same first
|
||||
<i>or</i> second component (<code>std::map</code> only
|
||||
guarantees uniqueness of the first component). Fast lookup is provided
|
||||
for both keys. The program features a tiny Spanish-English
|
||||
dictionary with online query of words in both languages.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This bidirectional map can be considered as a primitive precursor
|
||||
to the full-fledged container provided by
|
||||
<a href="../../bimap/index.html">Boost.Bimap</a>.
|
||||
</p>
|
||||
|
||||
<h2><a name="example5">Example 5: sequenced indices</a></h2>
|
||||
|
||||
<p>
|
||||
@@ -136,7 +149,7 @@ be defined as:
|
||||
<span class=keyword>struct</span> <span class=identifier>car_model</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>model</span><span class=special>;</span>
|
||||
<span class=identifier>std</span><span class=special>:</span><span class=identifier>string</span> <span class=identifier>manufacturer</span><span class=special>;</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>manufacturer</span><span class=special>;</span>
|
||||
<span class=keyword>int</span> <span class=identifier>price</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
@@ -161,17 +174,17 @@ involves having the manufactures stored in a separate
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>car_model</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>model</span><span class=special>;</span>
|
||||
<span class=identifier>car_manufacturer</span><span class=special>*</span> <span class=identifier>manufacturer</span><span class=special>;</span>
|
||||
<span class=keyword>int</span> <span class=identifier>price</span><span class=special>;</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>model</span><span class=special>;</span>
|
||||
<span class=keyword>const</span> <span class=identifier>car_manufacturer</span><span class=special>*</span> <span class=identifier>manufacturer</span><span class=special>;</span>
|
||||
<span class=keyword>int</span> <span class=identifier>price</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Although predefined Boost.MultiIndex key extractors can handle many
|
||||
situations involving pointers (see
|
||||
<a href="advanced_topics.html#advanced_key_extractors">advanced features
|
||||
of Boost.MultiIndex key extractors</a> in the Advanced topics section), this case
|
||||
<a href="tutorial/key_extraction.html#advanced_key_extractors">advanced features
|
||||
of Boost.MultiIndex key extractors</a> in the tutorial), this case
|
||||
is complex enough that a suitable key extractor has to be defined. The following
|
||||
utility cascades two key extractors:
|
||||
</p>
|
||||
@@ -209,7 +222,7 @@ of its associated <code>car_manufacturer</code> can be accomplished with
|
||||
<blockquote><pre>
|
||||
<span class=identifier>key_from_key</span><span class=special><</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>car_manufacturer</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>car_manufacturer</span><span class=special>::</span><span class=identifier>name</span><span class=special>>,</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>car_model</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>car_manufacturer</span> <span class=special>*,</span><span class=identifier>car_model</span><span class=special>::</span><span class=identifier>manufacturer</span><span class=special>></span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>car_model</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>car_manufacturer</span> <span class=special>*,&</span><span class=identifier>car_model</span><span class=special>::</span><span class=identifier>manufacturer</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
@@ -251,7 +264,7 @@ See <a href="../example/composite_keys.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex <a href="advanced_topics.html#composite_keys">
|
||||
Boost.MultiIndex <a href="tutorial/key_extraction.html#composite_keys">
|
||||
<code>composite_key</code></a> construct provides a flexible tool for
|
||||
creating indices with non-trivial sorting criteria.
|
||||
The program features a rudimentary simulation of a file system
|
||||
@@ -294,7 +307,7 @@ instance:
|
||||
<ul>
|
||||
<li>Implement additional commands, like <code>cp</code>.</li>
|
||||
<li>Add handling of absolute paths.</li>
|
||||
<li>Use <a href="advanced_topics.html#serialization">serialization</a>
|
||||
<li>Use <a href="tutorial/creation.html#serialization">serialization</a>
|
||||
to store and retrieve the filesystem state between program runs.</li>
|
||||
</ul>
|
||||
</p>
|
||||
@@ -333,6 +346,96 @@ data structure is implemented with <code>multi_index_container</code> by
|
||||
combining a sequenced index and an index of type <code>hashed_unique</code>.
|
||||
</p>
|
||||
|
||||
<h2><a name="example10">Example 10: random access indices</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/random_access.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The example resumes the text container introduced in
|
||||
<a href="#example5">example 5</a> and shows how substituting a random
|
||||
access index for a sequenced index allows for extra capabilities like
|
||||
efficient access by position and calculation of the offset of a given
|
||||
element into the container.
|
||||
</p>
|
||||
|
||||
<h2><a name="example11">Example 11: index rearrangement</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/rearrange.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There is a relatively common piece of urban lore claiming that
|
||||
a deck of cards must be shuffled seven times in a row to be perfectly
|
||||
mixed. The statement derives from the works of mathematician Persi
|
||||
Diaconis on <i>riffle shuffling</i>: this shuffling
|
||||
technique involves splitting the deck in two packets roughly the same
|
||||
size and then dropping the cards from both packets so that they become
|
||||
interleaved. It has been shown that when repeating this procedure
|
||||
seven times the statistical distribution of cards is reasonably
|
||||
close to that associated with a truly random permutation. A measure
|
||||
of "randomness" can be estimated by counting <i>rising sequences</i>:
|
||||
consider a permutation of the sequence 1,2, ... , <i>n</i>, a rising sequence
|
||||
is a maximal chain of consecutive elements <i>m</i>, <i>m+1</i>, ... , <i>m+r</i>
|
||||
such that they are arranged in ascending order. For instance, the permutation
|
||||
125364789 is composed of the two rising sequences 1234 and 56789,
|
||||
as becomes obvious by displaying the sequence like this,
|
||||
<span style="vertical-align:sub">1</span><span style="vertical-align:sub">2</span><span style="vertical-align:super">5</span><span style="vertical-align:sub">3</span><span style="vertical-align:super">6</span><span style="vertical-align:sub">4</span><span style="vertical-align:super">7</span><span style="vertical-align:super">8</span><span style="vertical-align:super">9</span>.
|
||||
The average number of rising sequences in a random permutation of
|
||||
<i>n</i> elements is (<i>n</i>+1)/2: by contrast, after a single riffle
|
||||
shuffle of an initially sorted deck of cards, there cannot be more than
|
||||
two rising sequences. The average number of rising sequences approximates
|
||||
to (<i>n</i>+1)/2 as the number of consecutive riffle shuffles increases,
|
||||
with seven shuffles yielding a close result for a 52-card poker deck.
|
||||
Brad Mann's paper
|
||||
<a href="http://www.dartmouth.edu/~chance/teaching_aids/books_articles/Mann.pdf">"How
|
||||
many times should you shuffle a deck of cards?"</a> provides a
|
||||
rigorous yet very accessible treatment of this subject.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The example program estimates the average number of rising sequences
|
||||
in a 52-card deck after repeated riffle shuffling as well as applying
|
||||
a completely random permutation. The deck is modeled by the following
|
||||
container:
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>random_access</span><span class=special><>,</span>
|
||||
<span class=identifier>random_access</span><span class=special><></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
where the first index stores the current arrangement of the deck, while
|
||||
the second index is used to remember the start position. This representation
|
||||
allows for an efficient implementation of a rising sequences counting
|
||||
algorithm in linear time.
|
||||
<a href="reference/rnd_indices.html#rearrange"><code>rearrange</code></a>
|
||||
is used to apply to the deck a shuffle performed externally on an
|
||||
auxiliary data structure.
|
||||
</p>
|
||||
|
||||
<h2><a name="example12">Example 12: using Boost.Interprocess allocators</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/ip_allocator.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex supports special allocators such as those provided by
|
||||
<a href="../../interprocess/index.html">Boost.Interprocess</a>,
|
||||
which allows for <code>multi_index_container</code>s to be placed in shared
|
||||
memory. The example features a front-end to a small book database
|
||||
implemented by means of a <code>multi_index_container</code> stored
|
||||
in a Boost.Interprocess memory mapped file. The reader can verify that several
|
||||
instances of the program correctly work simultaneously and immediately see
|
||||
the changes to the database performed by any other instance.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br>
|
||||
@@ -347,9 +450,9 @@ Tests
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised March 8th 2005</p>
|
||||
<p>Revised November 18th 2019</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2019 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Future work</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<link rel="start" href="index.html">
|
||||
<link rel="prev" href="tests.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="release_notes.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -33,47 +37,12 @@ principle driving the current internal design of <code>multi_index_container</co
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#ranked_indices">Ranked indices</a></li>
|
||||
<li><a href="#random_access_indices">Random access indices</a></li>
|
||||
<li><a href="#notifying">Notifying indices</a></li>
|
||||
<li><a href="#constraints">Constraints</a></li>
|
||||
<li><a href="#user_defined_indices">User-defined indices</a></li>
|
||||
<li><a href="#bimap">Bidirectional map</a></li>
|
||||
<li><a href="#indexed_maps">Indexed maps</a></li>
|
||||
<li><a href="#move_semantics">Move semantics</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="ranked_indices">Ranked indices</a></h2>
|
||||
|
||||
<p>
|
||||
Ordered indices are implemented using red-black trees; these trees
|
||||
can be augmented with additional information to obtain a type
|
||||
of data structure called
|
||||
<a href="http://pine.cs.yale.edu/pinewiki/OrderStatisticsTree"><i>order-statistics
|
||||
trees</i></a>, allowing for logarithmic search of the <i>n</i>-th element. It
|
||||
has been proposed that order-statistics trees be used to devise a new type of
|
||||
<i>ranked indices</i> that support <code>operator[]</code> while retaining
|
||||
the functionality of ordered indices.
|
||||
</p>
|
||||
|
||||
<h2><a name="random_access_indices">Random access indices</a></h2>
|
||||
|
||||
<p>
|
||||
These indices provide random access iterators and location of elements
|
||||
by their position ordinal. Although they seem at first glance to model
|
||||
the semantics of <code>std::vector</code>, random access indices present
|
||||
important differences:
|
||||
<ul>
|
||||
<li>Iterator and reference validity is preserved on insertion and deletion,</li>
|
||||
<li>memory contiguity is not provided,</li>
|
||||
<li>standard mutating algorithms (vg. <code>std::sort</code>) will in general
|
||||
not work with random access indices, as elements of a
|
||||
<code>multi_index_container</code> cannot be directly moved or swapped;</li>
|
||||
</ul>
|
||||
so it might be more accurate to regard this type of indices as a variation of
|
||||
sequenced indices with random access semantics.
|
||||
</p>
|
||||
|
||||
<h2><a name="notifying">Notifying indices</a></h2>
|
||||
|
||||
<p>
|
||||
@@ -165,19 +134,6 @@ simple enough to make them worth documenting so that the (bold)
|
||||
user can write implementations for her own indices.
|
||||
</p>
|
||||
|
||||
<h2><a name="bimap">Bidirectional map</a></h2>
|
||||
|
||||
<p>
|
||||
<a href="examples.html#example4">Example 4</a> in the examples section
|
||||
features a <i>bidirectional map</i>, implemented as a
|
||||
<code>multi_index_container</code> with two unique ordered indices. This particular
|
||||
structure is deemed important enough as to provide it as a separate
|
||||
class template, relying internally in <code>multi_index_container</code>. As
|
||||
feedback is collected from the users of Boost.MultiIndex, other singular
|
||||
instantiations of <code>multi_index_container</code> might be encapsulated
|
||||
to form a component library of ready to use containers.
|
||||
</p>
|
||||
|
||||
<h2><a name="indexed_maps">Indexed maps</a></h2>
|
||||
|
||||
<p>
|
||||
@@ -216,31 +172,6 @@ a careful study when designing the interface of a potential
|
||||
indexed map.
|
||||
</p>
|
||||
|
||||
<h2><a name="move_semantics">Move semantics</a></h2>
|
||||
|
||||
<p>
|
||||
Andrei Alexandrescu introduced a technique for simulating move
|
||||
constructors called Mojo (see his article in C/C++ User Journal
|
||||
<a href="http://www.cuj.com/documents/s=8246/cujcexp2102alexandr/">
|
||||
"Generic<Programming>: Move Constructors"</a>.) Move semantics
|
||||
alleviates the computational load involved in the creation and copying
|
||||
of temporary objects, specially for heavy classes as
|
||||
<code>multi_index_container</code>s are. David Abrahams and Gary Powell provide
|
||||
an alternative implementation of move semantics in their paper
|
||||
<a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html">
|
||||
"Clarification of Initialization of Class Objects by rvalues"</a> for
|
||||
the C++ Evolution Working Group.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Adding move semantics to <code>multi_index_container</code> is particularly
|
||||
beneficial when the container is used as an internal building block in other
|
||||
libraries (vg. relational database frameworks), enabling the efficient
|
||||
development of functions returning <code>multi_index_container</code>s. Without support
|
||||
for move semantics, this scheme is impractical and less elegant syntaxes
|
||||
should be resorted to.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="tests.html"><img src="prev.gif" alt="tests" border="0"><br>
|
||||
@@ -255,9 +186,9 @@ Release notes
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 5th 2005</p>
|
||||
<p>Revised April 19th 2015</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2015 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
|
After Width: | Height: | Size: 8.2 KiB |
@@ -5,15 +5,17 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Index</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<link rel="start" href="index.html">
|
||||
<link rel="next" href="tutorial/index.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost Multi-index Containers Library</h1>
|
||||
|
||||
<div class="prev_link"></div>
|
||||
<div class="up_link"></div>
|
||||
<div class="next_link"><a href="tutorial.html"><img src="next.gif" alt="tutorial" border="0"><br>
|
||||
<div class="prev_link"> </div>
|
||||
<div class="up_link"> </div>
|
||||
<div class="next_link"><a href="tutorial/index.html"><img src="next.gif" alt="tutorial" border="0"><br>
|
||||
Tutorial
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
@@ -29,12 +31,13 @@ borrowed from relational database terminology and allows for the specification o
|
||||
complex data structures in the spirit of multiply indexed relational tables where
|
||||
simple sets and maps are not enough. A wide selection of indices is provided,
|
||||
modeled after analogous STL containers like <code>std::set</code>,
|
||||
<code>std::list</code> and hashed sets.
|
||||
<code>std::list</code> and <code>std::unordered_set</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex features additional functionalities, like subobject searching,
|
||||
range querying and in-place updating of elements, which make it a convenient replacement
|
||||
range querying, in-place updating of elements and calculation of ranks,
|
||||
which make it a convenient replacement
|
||||
for <code>std::set</code> and <code>set::multiset</code> even when no multi-indexing
|
||||
capabilities are needed.
|
||||
</p>
|
||||
@@ -44,16 +47,16 @@ The versatile nature of Boost.MultiIndex allows for the specification of
|
||||
a wide spectrum of different data structures. The following are possible
|
||||
examples of use developed in the documentation:
|
||||
<ul>
|
||||
<li><a href="tutorial.html#multipe_sort">Sets with several iteration orders
|
||||
<li><a href="tutorial/basics.html#multiple_sort">Sets with several iteration orders
|
||||
and search criteria</a>.</li>
|
||||
<li><a href="tutorial.html#list_fast_lookup">Lists with fast lookup</a>
|
||||
<li><a href="tutorial/basics.html#list_fast_lookup">Lists with fast lookup</a>
|
||||
and/or without duplicates.</li>
|
||||
<li><a href="examples.html#example4">Bidirectional maps</a>, i.e. maps
|
||||
searchable either for key or value.</li>
|
||||
<li><a href="examples.html#example9">MRU (most recently used) lists</a>,
|
||||
structures keeping the <i>n</i> last referenced items, beginning with
|
||||
the newest ones.</li>
|
||||
<li><a href="advanced_topics.html#emulate_std_containers">Emulations of
|
||||
<li><a href="tutorial/techniques.html#emulate_std_containers">Emulations of
|
||||
standard containers</a> taking advantage of the extra functionalities
|
||||
provided by Boost.MultiIndex.</li>
|
||||
</ul>
|
||||
@@ -62,10 +65,8 @@ examples of use developed in the documentation:
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="tutorial.html">Tutorial</a></li>
|
||||
<li><a href="advanced_topics.html">Advanced topics</a></li>
|
||||
<li><a href="tutorial/index.html">Tutorial</a></li>
|
||||
<li><a href="reference/index.html">Reference</a></li>
|
||||
<li><a href="compiler_specifics.html">Compiler specifics</a></li>
|
||||
<li><a href="performance.html">Performance</a></li>
|
||||
<li><a href="examples.html">Examples</a></li>
|
||||
<li><a href="tests.html">Tests</a></li>
|
||||
@@ -76,17 +77,17 @@ examples of use developed in the documentation:
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"></div>
|
||||
<div class="up_link"></div>
|
||||
<div class="next_link"><a href="tutorial.html"><img src="next.gif" alt="tutorial" border="0"><br>
|
||||
<div class="prev_link"> </div>
|
||||
<div class="up_link"> </div>
|
||||
<div class="next_link"><a href="tutorial/index.html"><img src="next.gif" alt="tutorial" border="0"><br>
|
||||
Tutorial
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised March 15th 2005</p>
|
||||
<p>Revised November 7th 2025</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2025 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.5 KiB |
@@ -5,14 +5,18 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Performance</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<link rel="start" href="index.html">
|
||||
<link rel="prev" href="reference/key_extraction.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="examples.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Performance</h1>
|
||||
|
||||
<div class="prev_link"><a href="compiler_specifics.html"><img src="prev.gif" alt="compiler specifics" border="0"><br>
|
||||
Compiler specifics
|
||||
<div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
@@ -91,7 +95,7 @@ STL containers.
|
||||
<h2><a name="simulation">Manual simulation of a <code>multi_index_container</code></a></h2>
|
||||
|
||||
<p>
|
||||
The section of <a href="advanced_topics.html#simulate_std_containers">simulation
|
||||
The section on <a href="tutorial/techniques.html#emulate_std_containers">emulation
|
||||
of standard containers with <code>multi_index_container</code></a> shows the equivalence
|
||||
between single-index <code>multi_index_container</code>s and some STL containers. Let us now
|
||||
concentrate on the problem of simulating a <code>multi_index_container</code> with two
|
||||
@@ -107,7 +111,7 @@ Consider the following instantiation of <code>multi_index_container</code>:
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>>,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>>,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>indexed_t</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
@@ -154,8 +158,8 @@ inefficient, though: while insertion into the data structure is simple enough:
|
||||
<span class=identifier>manual_t2</span> <span class=identifier>c2</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// insert the element 5</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>=</span><span class=identifier>c1</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>5</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(&*</span><span class=identifier>t1</span><span class=special>);</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it1</span><span class=special>=</span><span class=identifier>c1</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>5</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(&*</span><span class=identifier>it1</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
deletion, on the other hand, necessitates a logarithmic search, whereas
|
||||
@@ -164,8 +168,8 @@ deletion, on the other hand, necessitates a logarithmic search, whereas
|
||||
<blockquote><pre>
|
||||
<span class=comment>// remove the element pointed to by it2</span>
|
||||
<span class=identifier>manual_t2</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it2</span><span class=special>=...;</span>
|
||||
<span class=identifier>c1</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(*</span><span class=identifier>it2</span><span class=special>);</span> <span class=comment>// watch out! performs in logarithmic time</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>it1</span><span class=special>);</span>
|
||||
<span class=identifier>c1</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(**</span><span class=identifier>it2</span><span class=special>);</span> <span class=comment>// watch out! performs in logarithmic time</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>it2</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
@@ -174,14 +178,14 @@ raw pointers, but with elements of type <code>manual_t1::iterator</code>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=identifier>manual_t1</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #0</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=identifier>manual_t1</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #0</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special><</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>,</span>
|
||||
<span class=identifier>it_compare</span><span class=special><</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special><</span><span class=keyword>int</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>manual_t2</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #1</span>
|
||||
<span class=special>></span> <span class=identifier>manual_t2</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #1</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
@@ -194,17 +198,17 @@ equivalent to those of <code>indexed_t</code>:
|
||||
<span class=identifier>manual_t2</span> <span class=identifier>c2</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// insert the element 5</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>=</span><span class=identifier>c1</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>5</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>t1</span><span class=special>);</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it1</span><span class=special>=</span><span class=identifier>c1</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>5</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>it1</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// remove the element pointed to by it2</span>
|
||||
<span class=identifier>manual_t2</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it2</span><span class=special>=...;</span>
|
||||
<span class=identifier>c1</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(*</span><span class=identifier>it2</span><span class=special>);</span> <span class=comment>// OK: constant time</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>it1</span><span class=special>);</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>it2</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The construction can be extended in a straightworward manner to
|
||||
The construction can be extended in a straightforward manner to
|
||||
handle more than two indices. In what follows, we will compare
|
||||
instantiations of <code>multi_index_container</code> against this sort of
|
||||
manual simulations.
|
||||
@@ -216,7 +220,7 @@ manual simulations.
|
||||
The gain in space consumption of <code>multi_index_container</code> with
|
||||
respect to its manual simulations is amenable to a very simple
|
||||
theoretical analysis. For simplicity, we will ignore alignment
|
||||
issues (which in general play in favor of <code>multi_index_container</code>.)
|
||||
issues (which in general play in favor of <code>multi_index_container</code>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -226,7 +230,7 @@ each index. Thus the node size is
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<i>S<sub>I</sub></i> = <i>e</i> + <i>h</i><sub>0</sub> + ··· +
|
||||
<i>S<sub>I</sub></i> = <i>e</i> + <i>h</i><sub>0</sub> + ··· +
|
||||
<i>h</i><sub><i>N</i>-1</sub>, where<br>
|
||||
<i>e</i> = size of the element,<br>
|
||||
<i>h</i><sub><i>i</i></sub> = size of the <i>i</i>-th header.
|
||||
@@ -237,13 +241,13 @@ On the other hand, the manual simulation allocates <i>N</i> nodes per
|
||||
element, the first holding the elements themselves and the rest
|
||||
storing iterators to the "base" container. In practice, an iterator
|
||||
merely holds a raw pointer to the node it is associated to, so its size
|
||||
is independent of the type of the elements. Suming all contributions,
|
||||
is independent of the type of the elements. Summing all contributions,
|
||||
the space allocated per element in a manual simulation is
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<i>S<sub>M</sub></i> = (<i>e</i> + <i>h</i><sub>0</sub>) +
|
||||
(<i>p</i> + <i>h</i><sub>1</sub>) + ··· +
|
||||
(<i>p</i> + <i>h</i><sub>1</sub>) + ··· +
|
||||
(<i>p</i> + <i>h</i><sub><i>N</i>-1</sub>) =
|
||||
<i>S<sub>I</sub></i> + (<i>N</i>-1)<i>p</i>, where<br>
|
||||
<i>p</i> = size of a pointer.<br>
|
||||
@@ -263,7 +267,25 @@ then as:
|
||||
|
||||
<p>
|
||||
The formula shows that <code>multi_index_container</code> is more efficient
|
||||
with regard to memory consumption as the number of indices grow.
|
||||
with regard to memory consumption as the number of indices grow. An implicit
|
||||
assumption has been made that headers of <code>multi_index_container</code>
|
||||
index nodes are the same size that their analogues in STL containers; but there
|
||||
is a particular case in which this is often not the case: ordered indices use a
|
||||
<a href="tutorial/indices.html#ordered_node_compression">spatial optimization
|
||||
technique</a> which is not present in many implementations of
|
||||
<code>std::set</code>, giving an additional advantage to
|
||||
<code>multi_index_container</code>s of one system word per ordered index.
|
||||
Taking this fact into account, the former formula can be adjusted to:
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<i>S<sub>I</sub></i> / <i>S<sub>M</sub></i> =
|
||||
<i>S<sub>I</sub></i> / (<i>S<sub>I</sub></i> + (<i>N</i>-1)<i>p</i> + <i>Ow</i>),
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
where <i>O</i> is the number of ordered indices of the container, and <i>w</i>
|
||||
is the system word size (typically 4 bytes on 32-bit architectures).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -289,9 +311,9 @@ will see later, the reduction can be very significative for
|
||||
</p>
|
||||
|
||||
<p>In the special case of <code>multi_index_container</code>s with only one index,
|
||||
the best we can hope for is equal performance: the tests show that the
|
||||
performance degradation in this particular situation ranges from negligible
|
||||
to small, depending on the compiler used.
|
||||
resulting performance will roughly match that of the STL equivalent containers:
|
||||
tests show that there is at most a negligible degradation with respect to STL,
|
||||
and even in some cases a small improvement.
|
||||
</p>
|
||||
|
||||
<h2><a name="tests">Performance tests</a></h2>
|
||||
@@ -314,15 +336,33 @@ has been measured for different instantiations of <code>multi_index_container</c
|
||||
at values of <i>n</i> 1,000, 10,000 and 100,000,
|
||||
and its execution time compared with that of the equivalent algorithm
|
||||
for the corresponding manual simulation of the data structure based on
|
||||
STL containers. The following compilers have been used:
|
||||
<ul>
|
||||
<li>GNU GCC 3.3.1 for Cygwin 1.5.7,</li>
|
||||
<li>Intel C++ Compiler for Windows 32-bit 7.1,</li>
|
||||
<li>Microsoft Visual C++ 6.0 Service Pack 5,</li>
|
||||
</ul>
|
||||
with their default release settings. All tests were performed on a Wintel
|
||||
box equipped with a P4 1.5GHz processor and 256 MB RAM, running
|
||||
Microsoft Windows 2000 Professional SP2.
|
||||
STL containers. The table below describes the test environments used.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0" cellpadding="5">
|
||||
<caption><b>Tests environments.</b></caption>
|
||||
<tr>
|
||||
<th>Compiler</th>
|
||||
<th>Settings</th>
|
||||
<th>OS and CPU</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GCC 3.4.5 (mingw special)</td>
|
||||
<td><code>-O3</code></td>
|
||||
<td>Windows 2000 Pro on P4 1.5 GHz, 256 MB RAM</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td>Intel C++ 7.1</td>
|
||||
<td>default release settings</td>
|
||||
<td>Windows 2000 Pro on P4 1.5 GHz, 256 MB RAM</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft Visual C++ 8.0</td>
|
||||
<td>default release settings, <code>_SECURE_SCL=0</code></td>
|
||||
<td>Windows XP on P4 Xeon 3.2 GHz, 1 GB RAM</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -357,14 +397,14 @@ which is functionally equivalent to <code>std::set<int></code>.
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">100%</td>
|
||||
<td align="center">100%</td>
|
||||
<td align="center">100%</td>
|
||||
<td align="center">80%</td>
|
||||
<td align="center">80%</td>
|
||||
<td align="center">80%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 1: Relative memory consumption of <code>multi_index_container</code> with 1
|
||||
@@ -372,8 +412,8 @@ ordered index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The figures confirm that in this case <code>multi_index_container</code> nodes are the
|
||||
same size than those of its <code>std::set</code> counterpart.
|
||||
The reduction in memory usage is accounted for by the optimization technique implemented
|
||||
in Boost.MultiIndex ordered indices, as <a href="#spatial_efficiency">explained above</a>.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_1r">Execution time</a></h4>
|
||||
@@ -385,11 +425,12 @@ width="556" height="372"><br>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As expected, <code>multi_index_container</code> does perform in this case somewhat
|
||||
worse than <code>std::set</code>. The degradation is within 10% for ICC and
|
||||
MSVC compilers, while in GCC peaks to 20%, which can be significative
|
||||
in certain applications. This latter result is presumably accounted for by
|
||||
a lower quality of the optimizing stage carried out by GCC.
|
||||
Somewhat surprisingly, <code>multi_index_container</code> performs slightly
|
||||
better than <code>std::set</code>. A very likely explanation for this behavior
|
||||
is that the lower memory consumption of <code>multi_index_container</code>
|
||||
results in a higher processor cache hit rate.
|
||||
The improvement is smallest for GCC, presumably because the worse quality of
|
||||
this compiler's optimizer masks the cache-related benefits.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_1s">Results for 1 sequenced index</a></h3>
|
||||
@@ -416,9 +457,9 @@ which is functionally equivalent to <code>std::list<int></code>.
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">100%</td>
|
||||
@@ -432,7 +473,7 @@ sequenced index.</b>
|
||||
|
||||
<p>
|
||||
The figures confirm that in this case <code>multi_index_container</code> nodes are the
|
||||
same size than those of its <code>std::list</code> counterpart.
|
||||
same size as those of its <code>std::list</code> counterpart.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_1s">Execution time</a></h4>
|
||||
@@ -444,9 +485,10 @@ width="556" height="372"><br>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As in the former case, <code>multi_index_container</code> does not attain the performance
|
||||
of its STL counterpart. Again, worst results are those of GCC, with a
|
||||
degradation of up to 20% , while ICC and MSVC do not exceed a mere 5%.
|
||||
<code>multi_index_container</code> does not attain the performance
|
||||
of its STL counterpart, although the figures are close. Again, the worst results
|
||||
are those of GCC, with a degradation of up to 7%, while ICC and MSVC do not
|
||||
exceed a mere 5%.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_2r">Results for 2 ordered indices</a></h3>
|
||||
@@ -470,14 +512,14 @@ The following instantiation of <code>multi_index_container</code> was tested:
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">90%</td>
|
||||
<td align="center">90%</td>
|
||||
<td align="center">90%</td>
|
||||
<td align="center">70%</td>
|
||||
<td align="center">70%</td>
|
||||
<td align="center">70%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 3: Relative memory consumption of <code>multi_index_container</code> with 2
|
||||
@@ -485,8 +527,8 @@ ordered indices.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These results concinde with the theoretical formula for
|
||||
<i>S<sub>I</sub></i>=36 and <i>p</i>=4.
|
||||
These results coincide with the theoretical formula for
|
||||
<i>S<sub>I</sub></i> = 28, <i>N</i> = <i>O</i> = 2 and <i>p</i> = <i>w</i> = 4.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_2r">Execution time</a></h4>
|
||||
@@ -500,7 +542,9 @@ width="556" height="372"><br>
|
||||
<p>
|
||||
The experimental results confirm our hypothesis that <code>multi_index_container</code>
|
||||
provides an improvement on execution time by an approximately constant factor,
|
||||
which in this case ranges from 65% to 75% depending on the compiler.
|
||||
which in this case lies around 60%. There is no obvious explanation for the
|
||||
increased advantage of <code>multi_index_container</code> in MSVC for
|
||||
<i>n</i>=10<sup>5</sup>.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_1r1s">Results for 1 ordered index + 1 sequenced index</a></h3>
|
||||
@@ -524,14 +568,14 @@ The following instantiation of <code>multi_index_container</code> was tested:
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">87.5%</td>
|
||||
<td align="center">87.5%</td>
|
||||
<td align="center">87.5%</td>
|
||||
<td align="center">75%</td>
|
||||
<td align="center">75%</td>
|
||||
<td align="center">75%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 4: Relative memory consumption of <code>multi_index_container</code> with 1
|
||||
@@ -539,8 +583,8 @@ ordered index + 1 sequenced index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These results concinde with the theoretical formula for
|
||||
<i>S<sub>I</sub></i>=28 and <i>p</i>=4.
|
||||
These results coincide with the theoretical formula for
|
||||
<i>S<sub>I</sub></i> = 24, <i>N</i> = 2, <i>O</i> = 1 and <i>p</i> = <i>w</i> = 4.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_1r1s">Execution time</a></h4>
|
||||
@@ -556,17 +600,13 @@ width="556" height="372"><br>
|
||||
<p>
|
||||
For <i>n</i>=10<sup>3</sup> and <i>n</i>=10<sup>4</sup>, the results
|
||||
are in agreement with our theoretical analysis, showing a constant factor
|
||||
improvement of 60-75% with respect to the STL-based manual simulation.
|
||||
improvement of 50-65% with respect to the STL-based manual simulation.
|
||||
Curiously enough, this speedup gets even higher when
|
||||
<i>n</i>=10<sup>5</sup> for two of the compilers (35% for ICC,
|
||||
25% for MSVC.) In order to rule out spurious results, the tests
|
||||
have been run many times, yielding similar outcoumes. A tentative
|
||||
explanation of this unexpected behavior may point to a degradation in
|
||||
the execution time of the manual simulation, attributable to poor
|
||||
performance of the standard STL allocator in ICC and MSVC when dealing
|
||||
with many objects of diverse sizes (the manual simulation is comprised of
|
||||
an <code>std::set</code> and a <code>std::list</code>, which demand
|
||||
differently sized nodes.)
|
||||
<i>n</i>=10<sup>5</sup> for two of the compilers, namely GCC and ICC.
|
||||
In order to rule out spurious results, the tests
|
||||
have been run many times, yielding similar outcomes. Both test environments
|
||||
are deployed on the same machine, which points to some OS-related reason for
|
||||
this phenomenon.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_3r">Results for 3 ordered indices</a></h3>
|
||||
@@ -591,14 +631,14 @@ The following instantiation of <code>multi_index_container</code> was tested:
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">86.7%</td>
|
||||
<td align="center">86.7%</td>
|
||||
<td align="center">86.7%</td>
|
||||
<td align="center">66.7%</td>
|
||||
<td align="center">66.7%</td>
|
||||
<td align="center">66.7%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 5: Relative memory consumption of <code>multi_index_container</code> with 3
|
||||
@@ -606,9 +646,8 @@ ordered indices.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These results concinde with the theoretical formula for
|
||||
<i>S<sub>I</sub></i>=52 and <i>p</i>=4.
|
||||
|
||||
These results coincide with the theoretical formula for
|
||||
<i>S<sub>I</sub></i> = 40, <i>N</i> = <i>O</i> = 3 and <i>p</i> = <i>w</i> = 4.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_3r">Execution time</a></h4>
|
||||
@@ -620,7 +659,7 @@ width="556" height="372"><br>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Execution time for this case is between 55% and 65% lower than achieved with
|
||||
Execution time for this case is between 45% and 55% lower than achieved with
|
||||
an STL-based manual simulation of the same data structure.
|
||||
</p>
|
||||
|
||||
@@ -646,14 +685,14 @@ The following instantiation of <code>multi_index_container</code> was tested:
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">84.6%</td>
|
||||
<td align="center">84.6%</td>
|
||||
<td align="center">84.6%</td>
|
||||
<td align="center">69.2%</td>
|
||||
<td align="center">69.2%</td>
|
||||
<td align="center">69.2%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 6: Relative memory consumption of <code>multi_index_container</code> with 2
|
||||
@@ -661,8 +700,8 @@ ordered indices + 1 sequenced index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These results concinde with the theoretical formula for
|
||||
<i>S<sub>I</sub></i>=44 and <i>p</i>=4.
|
||||
These results coincide with the theoretical formula for
|
||||
<i>S<sub>I</sub></i> = 36, <i>N</i> = 3, <i>O</i> = 2 and <i>p</i> = <i>w</i> = 4.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_2r1s">Execution time</a></h4>
|
||||
@@ -686,21 +725,20 @@ factor, which ranges from 45% to 55%.
|
||||
We have shown that <code>multi_index_container</code> outperforms, both in space and
|
||||
time efficiency, equivalent data structures obtained from the manual
|
||||
combination of STL containers. This improvement gets larger when the number
|
||||
of indices increase.
|
||||
of indices increases.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the special case of replacing standard containers with single-indexed
|
||||
<code>multi_index_container</code>s, the programmer should balance the benefits brought on
|
||||
by Boost.MultiIndex (subobject searching, in-place updating, etc.) against the
|
||||
resulting degradation in execution time. Depending on the compiler, this degradation
|
||||
can reach up to 20% of the original time.
|
||||
<code>multi_index_container</code>s, the performance of Boost.MultiIndex
|
||||
is comparable with that of the tested STL implementations, and can even yield
|
||||
some improvements both in space consumption and execution time.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="compiler_specifics.html"><img src="prev.gif" alt="compiler specifics" border="0"><br>
|
||||
Compiler specifics
|
||||
<div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
@@ -711,9 +749,9 @@ Examples
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 18th 2005</p>
|
||||
<p>Revised November 7th 2025</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2025 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -5,14 +5,18 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="../tutorial/techniques.html">
|
||||
<link rel="up" href="../index.html">
|
||||
<link rel="next" href="multi_index_container.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Reference</h1>
|
||||
|
||||
<div class="prev_link"><a href="../advanced_topics.html"><img src="../prev.gif" alt="advanced topics" border="0"><br>
|
||||
Advanced topics
|
||||
<div class="prev_link"><a href="../tutorial/techniques.html"><img src="../prev.gif" alt="techniques" border="0"><br>
|
||||
Techniques
|
||||
</a></div>
|
||||
<div class="up_link"><a href="../index.html"><img src="../up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
@@ -30,8 +34,10 @@ Index
|
||||
<li><a href="multi_index_container.html">Class template <code>multi_index_container</code></a></li>
|
||||
<li><a href="indices.html">Index reference</a></li>
|
||||
<li><a href="ord_indices.html">Ordered indices</a></li>
|
||||
<li><a href="rnk_indices.html">Ranked indices</a></li>
|
||||
<li><a href="hash_indices.html">Hashed indices</a></li>
|
||||
<li><a href="seq_indices.html">Sequenced indices</a></li>
|
||||
<li><a href="rnd_indices.html">Random access indices</a></li>
|
||||
<li><a href="key_extraction.html">Key Extraction</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -54,6 +60,13 @@ The following dependencies among headers of Boost.MultiIndex hold:
|
||||
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="rnk_indices.html#synopsis">
|
||||
<code>"boost/multi_index/ranked_index.hpp"</code></a> includes
|
||||
<ul>
|
||||
<li><a href="indices.html#tag_synopsis">
|
||||
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="hash_indices.html#synopsis">
|
||||
<code>"boost/multi_index/hashed_index.hpp"</code></a> includes
|
||||
<ul>
|
||||
@@ -68,6 +81,13 @@ The following dependencies among headers of Boost.MultiIndex hold:
|
||||
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="rnd_indices.html#synopsis">
|
||||
<code>"boost/multi_index/random_access_index.hpp"</code></a> includes
|
||||
<ul>
|
||||
<li><a href="indices.html#tag_synopsis">
|
||||
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="key_extraction.html#synopsis"><code>"boost/multi_index/key_extractors.hpp"</code></a>
|
||||
includes
|
||||
<ul>
|
||||
@@ -76,7 +96,9 @@ The following dependencies among headers of Boost.MultiIndex hold:
|
||||
<li><a href="key_extraction.html#member_synopsis">
|
||||
<code>"boost/multi_index/member.hpp"</code></a>,</li>
|
||||
<li><a href="key_extraction.html#mem_fun_synopsis">
|
||||
<code>"boost/multi_index/mem_fun.hpp"</code></a> and</li>
|
||||
<code>"boost/multi_index/mem_fun.hpp"</code></a>,</li>
|
||||
<li><a href="key_extraction.html#global_fun_synopsis">
|
||||
<code>"boost/multi_index/global_fun.hpp"</code></a> and</li>
|
||||
<li><a href="key_extraction.html#composite_key_synopsis">
|
||||
<code>"boost/multi_index/composite_key.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
@@ -101,8 +123,8 @@ object modules.
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="../advanced_topics.html"><img src="../prev.gif" alt="advanced topics" border="0"><br>
|
||||
Advanced topics
|
||||
<div class="prev_link"><a href="../tutorial/techniques.html"><img src="../prev.gif" alt="techniques" border="0"><br>
|
||||
Techniques
|
||||
</a></div>
|
||||
<div class="up_link"><a href="../index.html"><img src="../up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
@@ -113,9 +135,9 @@ Index
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 30th 2005</p>
|
||||
<p>Revised November 24th 2015</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2015 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Index reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="multi_index_container.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="ord_indices.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -48,6 +52,7 @@ Ordered indices
|
||||
<li><a href="#other_indices">Other types</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#views">Index views</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="index_concepts">Index concepts</a></h2>
|
||||
@@ -76,8 +81,8 @@ appropriate interface of some index of the <code>multi_index_container</code>;
|
||||
these operations, however, do have an impact on all other indices as
|
||||
well: for instance, insertion through a given index may fail because
|
||||
there exists another index which bans the operation in order to preserve
|
||||
its invariant (like uniqueness of elements.) This circumstance, rather
|
||||
than an obstacle, yields much of the power of Boost.MultiIndex:
|
||||
its invariant (like uniqueness of elements). This circumstance, rather
|
||||
than being an obstacle, yields much of the power of Boost.MultiIndex:
|
||||
equivalent constructions based on manual composition of standard
|
||||
containers would have to add a fair amount of code in order to
|
||||
globally preserve the invariants of each container while guaranteeing
|
||||
@@ -98,14 +103,15 @@ six primitives:
|
||||
</ul>
|
||||
The last two primitives deserve some further explanation: in order to
|
||||
guarantee the invariants associated to each index (e.g. some definite
|
||||
ordering,) elements of a <code>multi_index_container</code> are not mutable.
|
||||
ordering), elements of a <code>multi_index_container</code> are not mutable.
|
||||
To overcome this restriction, indices expose member functions
|
||||
for updating and modifying, which allow for the mutation of elements
|
||||
for replacement and modification which allow for the mutation of elements
|
||||
in a controlled fashion. Immutability of elements does not significantly
|
||||
impact the interface of ordered indices, as it is based upon that of
|
||||
<code>std::set</code> and <code>std:multiset</code>, and these containers
|
||||
impact the interfaces of ordered and hashed indices, as they are based upon
|
||||
those of associative and unordered associative containers, respectively,
|
||||
and these containers
|
||||
also have non-mutable elements; but it may come as a surprise when dealing
|
||||
with sequenced indices, which are designed upon the functionality provided
|
||||
with sequenced and random access indices, which are designed upon the functionality provided
|
||||
by <code>std::list</code>.
|
||||
</p>
|
||||
|
||||
@@ -113,13 +119,11 @@ by <code>std::list</code>.
|
||||
These global operations are not directly exposed to the user, but rather
|
||||
they are wrapped as appropriate by each index (for instance, ordered indices
|
||||
provide a set-like suite of insertion member functions, whereas sequenced
|
||||
indices do have <code>push_back</code> and <code>push_front</code>
|
||||
operations.) Boost.MultiIndex poses no particular conditions on
|
||||
the interface of indices, save that they must model
|
||||
<a href="http://www.sgi.com/tech/stl/Container.html">
|
||||
<code>Container</code></a> (without the requirement of being
|
||||
<a href="http://www.sgi.com/tech/stl/Assignable.html">
|
||||
<code>Assignable</code></a>.)
|
||||
and random access indices have <code>push_back</code> and <code>push_front</code>
|
||||
operations). Boost.MultiIndex poses no particular conditions on
|
||||
the interface of indices, although each index provided satisfies the C++ requirements for
|
||||
standard containers to the maximum extent possible within the conceptual framework
|
||||
of the library.
|
||||
</p>
|
||||
|
||||
<h2><a name="complexity_signature">Complexity signature</a></h2>
|
||||
@@ -152,16 +156,16 @@ with <code>N</code> indices labelled <code>0</code>,...,<code>N-1</code>
|
||||
whose complexity signatures are
|
||||
(<code>c<sub>i</sub></code>,<code>i<sub>i</sub></code>,<code>h<sub>i</sub></code>,<code>d<sub>i</sub></code>,<code>r<sub>i</sub></code>,<code>m<sub>i</sub></code>);
|
||||
the insertion of an element in such a container is then of complexity
|
||||
<code>O(i<sub>0</sub>(n)+···+i<sub>N-1</sub>(n))</code> where <code>n</code>
|
||||
<code>O(i<sub>0</sub>(n)+···+i<sub>N-1</sub>(n))</code> where <code>n</code>
|
||||
is the number of elements. To abbreviate notation, we adopt the
|
||||
following definitions:
|
||||
<ul>
|
||||
<li><code>C(n)=c<sub>0</sub>(n)+···+c<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>I(n)=i<sub>0</sub>(n)+···+i<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>H(n)=h<sub>0</sub>(n)+···+h<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>D(n)=d<sub>0</sub>(n)+···+d<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>R(n)=r<sub>0</sub>(n)+···+r<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>M(n)=m<sub>0</sub>(n)+···+m<sub>N-1</sub>(n)</code>.</li>
|
||||
<li><code>C(n)=c<sub>0</sub>(n)+···+c<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>I(n)=i<sub>0</sub>(n)+···+i<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>H(n)=h<sub>0</sub>(n)+···+h<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>D(n)=d<sub>0</sub>(n)+···+d<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>R(n)=r<sub>0</sub>(n)+···+r<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>M(n)=m<sub>0</sub>(n)+···+m<sub>N-1</sub>(n)</code>.</li>
|
||||
</ul>
|
||||
For instance, consider a <code>multi_index_container</code> with two ordered indices,
|
||||
for which <code>i(n)=log(n)</code>, and a sequenced index with <code>i(n)=1</code>
|
||||
@@ -185,11 +189,16 @@ index specifiers
|
||||
<li><a href="ord_indices.html#unique_non_unique"><code>ordered_unique</code> and
|
||||
<code>ordered_non_unique</code></a> for
|
||||
<a href="ord_indices.html">ordered indices</a>,</li>
|
||||
<li><a href="rnk_indices.html#unique_non_unique"><code>ranked_unique</code> and
|
||||
<code>ranked_non_unique</code></a> for
|
||||
<a href="rnk_indices.html">ranked indices</a>,</li>
|
||||
<li><a href="hash_indices.html#unique_non_unique"><code>hashed_unique</code> and
|
||||
<code>hashed_non_unique</code></a> for
|
||||
<a href="hash_indices.html">hashed indices</a>,</li>
|
||||
<li>and <a href="seq_indices.html#sequenced"><code>sequenced</code></a> for
|
||||
<a href="seq_indices.html">sequenced indices</a>.</li>
|
||||
<li><a href="seq_indices.html#sequenced"><code>sequenced</code></a> for
|
||||
<a href="seq_indices.html">sequenced indices</a>,</li>
|
||||
<li>and <a href="rnd_indices.html#random_access"><code>random_access</code></a> for
|
||||
<a href="rnd_indices.html">random access indices</a>.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
@@ -203,7 +212,7 @@ index specifiers
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>template</span><span class=special><</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>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>indexed_by</span><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
@@ -214,24 +223,19 @@ index specifiers
|
||||
<h3><a name="indexed_by">Class template <code>indexed_by</code></a></h3>
|
||||
|
||||
<p>
|
||||
<code>indexed_by</code> is a model of
|
||||
<a href="../../../../libs/mpl/doc/refmanual/random-access-sequence.html">
|
||||
<code>MPL Random Access Sequence</code></a> and
|
||||
<a href="../../../../libs/mpl/doc/refmanual/extensible-sequence.html">
|
||||
<code>MPL Extensible Sequence</code></a> meant to be used to specify a
|
||||
<code>indexed_by</code> is meant to be used to specify a
|
||||
compile-time list of indices as the <code>IndexSpecifierList</code> of
|
||||
<code>multi_index_container</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>template</span><span class=special><</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>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>indexed_by</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Each user-provided element of <code>indexed_list</code> must be an index
|
||||
specifier. At least an element must be provided. The maximum number of elements
|
||||
of an <code>indexed_by</code> sequence is implementation defined.
|
||||
specifier. At least an element must be provided.
|
||||
</p>
|
||||
|
||||
<h2><a name="tags">Tags</a></h2>
|
||||
@@ -255,7 +259,7 @@ class template <a href="#tag"><code>tag</code></a>.
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Ts</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>tag</span><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
@@ -271,15 +275,13 @@ sequence of tags to be assigned to an index in instantiation time.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Ts</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>tag</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Elements of <code>tag</code> can be any type, though the user is expected
|
||||
to provide classes with mnemonic names. Duplicate elements are not allowed.
|
||||
The maximum number of elements of a <code>tag</code> instantiation is
|
||||
implementation defined.
|
||||
</p>
|
||||
|
||||
<h2><a name="index_catalog">Indices provided by Boost.MultiIndex</a></h2>
|
||||
@@ -293,7 +295,11 @@ elements, as described in the <a href="key_extraction.html">key extraction
|
||||
reference</a>.
|
||||
<ul>
|
||||
<li><a href="ord_indices.html">Ordered indices</a> sort the elements
|
||||
on the key and provide fast lookup capabilites.</li>
|
||||
on the key and provide fast lookup capabilities.</li>
|
||||
<li><a href="rnk_indices.html">Ranked indices</a> are a variation of
|
||||
ordered indices providing extra operations based on
|
||||
<i>rank</i>, the numerical position of an element
|
||||
in the sequence.</li>
|
||||
<li><a href="hash_indices.html">Hashed indices</a> offer high
|
||||
efficiency access through hashing techniques.</li>
|
||||
</ul>
|
||||
@@ -304,7 +310,48 @@ reference</a>.
|
||||
<p>
|
||||
<ul>
|
||||
<li><a href="seq_indices.html">Sequenced indices</a> allow to arrange
|
||||
elements as in a bidirectional list. </li>
|
||||
elements as in a bidirectional list.</li>
|
||||
<li><a href="rnd_indices.html">Random access indices</a> provide
|
||||
constant time positional access and free ordering of elements.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="views">Index views</a></h2>
|
||||
|
||||
<p>
|
||||
The following concept is used by the rearrange facilities of non-key-based
|
||||
indices. Given an index <code>i</code> of type <code>Index</code>, a <i>view
|
||||
of <code>i</code></i> is any range [<code>first</code>,<code>last</code>)
|
||||
where <code>first</code> and <code>last</code> are input iterators such that
|
||||
<ol>
|
||||
<li>the associated value type of <code>Iterator</code> is convertible
|
||||
to <code>const Index::value_type&</code>
|
||||
</li>
|
||||
<li>and each of the elements of <code>i</code> appears exactly once in
|
||||
[<code>first</code>,<code>last</code>).
|
||||
</li>
|
||||
</ol>
|
||||
Note that the view refers to the actual elements of <code>i</code>, not to
|
||||
copies of them. Additionally, a view is said to be <i>free</i> if its traversal
|
||||
order is not affected by changes in the traversal order of <code>i</code>.
|
||||
Examples of free views are:
|
||||
<ul>
|
||||
<li>[<code>c.begin()</code>,<code>c.end()</code>), where <code>c</code> is
|
||||
any container of reference wrappers (from
|
||||
<a href="../../../../doc/html/ref.html">Boost.Ref</a>) to the elements
|
||||
of <code>i</code> containing exactly one reference to every element.
|
||||
</li>
|
||||
<li>[<code>i'.begin()</code>,<code>i'.end()</code>), where <code>i'</code> is
|
||||
any index belonging to the same <code>multi_index_container</code>
|
||||
as <code>i</code>, except <code>i</code> itself.
|
||||
</li>
|
||||
<li>
|
||||
Any range which is a permutation of the ones described above, as for
|
||||
instance [<code>c.rbegin()</code>,<code>c.rend()</code>), or
|
||||
ranges obtained from the former with the aid of
|
||||
<a href="../../../../libs/iterator/doc/permutation_iterator.html">
|
||||
<code>permutation_iterator</code></a> from Boost.Iterator.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
@@ -322,9 +369,9 @@ Ordered indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 30th 2005</p>
|
||||
<p>Revised October 25th 2025</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2025 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - multi_index_container reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="index.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="indices.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -84,6 +88,8 @@ synopsis</a>
|
||||
</h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>initializer_list</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
@@ -95,10 +101,15 @@ synopsis</a>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
|
||||
|
||||
<span class=comment>// multi_index_container global functions for index retrieval:</span>
|
||||
|
||||
@@ -108,7 +119,7 @@ synopsis</a>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>);</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
@@ -116,7 +127,7 @@ synopsis</a>
|
||||
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>);</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
@@ -124,7 +135,7 @@ synopsis</a>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>);</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
@@ -132,7 +143,7 @@ synopsis</a>
|
||||
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>);</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// multi_index_container global functions for projection of iterators:</span>
|
||||
|
||||
@@ -140,9 +151,9 @@ synopsis</a>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
@@ -151,9 +162,9 @@ synopsis</a>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
@@ -162,9 +173,9 @@ synopsis</a>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
@@ -173,9 +184,9 @@ synopsis</a>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
@@ -224,16 +235,15 @@ and for access to the indices held.
|
||||
<p>
|
||||
A <code>multi_index_container</code> type is instantiated with the type of the
|
||||
elements contained and a non-empty
|
||||
<a href="../../../../libs/mpl/doc/refmanual/forward-sequence.html">
|
||||
<code>MPL Forward Sequence</code></a> specifying which indices conform the
|
||||
class.
|
||||
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</a>
|
||||
specifying which indices conform the class.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For convenience of use, all public methods and types of the first index
|
||||
specified are inherited by <code>multi_index_container</code>. This also includes global
|
||||
operators and functions associated with the index (vg. comparison and
|
||||
<code>swap</code>.)
|
||||
<code>swap</code>).
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -253,6 +263,7 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>iterator_type_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>const_iterator_type_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>node_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// nested class templates:</span>
|
||||
|
||||
@@ -260,52 +271,75 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
|
||||
<span class=comment>// construct/copy/destroy:</span>
|
||||
|
||||
<span class=identifier>multi_index_container</span><span class=special>();</span>
|
||||
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(
|
||||
</span><span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
|
||||
</span><span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&</span> <span class=identifier>args_list</span><span class=special>,
|
||||
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
|
||||
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
|
||||
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special><</span><span class=identifier>Value</span><span class=special>></span> <span class=identifier>list</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
|
||||
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>);</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>);</span>
|
||||
|
||||
<span class=special>~</span><span class=identifier>multi_index_container</span><span class=special>();</span>
|
||||
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=keyword>operator</span><span class=special>=(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=keyword>operator</span><span class=special>=(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=keyword>operator</span><span class=special>=(</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special><</span><span class=identifier>Value</span><span class=special>></span> <span class=identifier>list</span><span class=special>)</span>
|
||||
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// retrieval of indices</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>();</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// projection of iterators</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=comment>// multi_index_container associated global class templates:</span>
|
||||
@@ -320,22 +354,26 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>nth_index_const_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index_const_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
@@ -348,9 +386,9 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>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><</span><span class=identifier>N</span><span class=special>>();</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>get</span><span class=special><</span><span class=identifier>N</span><span class=special>>();</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
@@ -359,9 +397,9 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>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><</span><span class=identifier>N</span><span class=special>>();</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>get</span><span class=special><</span><span class=identifier>N</span><span class=special>>();</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
@@ -370,9 +408,9 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>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><</span><span class=identifier>Tag</span><span class=special>>();</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>get</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>();</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
@@ -381,9 +419,9 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span><span class=keyword>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><</span><span class=identifier>Tag</span><span class=special>>();</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>get</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>();</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// multi_index_container global functions for projection of iterators:</span>
|
||||
@@ -392,56 +430,56 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// comparison:</span>
|
||||
@@ -487,26 +525,48 @@ scheme outlined in the
|
||||
<p>
|
||||
<code>multi_index_container</code> is instantiated with the following types:
|
||||
<ol>
|
||||
<li><code>Value</code> is the
|
||||
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>
|
||||
type of the elements contained.</li>
|
||||
<li><code>Value</code> is the type of the elements contained. <code>Value</code> must be
|
||||
<code>Erasable</code> from <code>multi_index_container</code>.
|
||||
</li>
|
||||
<li><code>IndexSpecifierList</code> specifies the indices that the
|
||||
<code>multi_index_container</code> is composed of. It must be a non-empty
|
||||
<a href="../../../../libs/mpl/doc/refmanual/forward-sequence.html">
|
||||
<code>MPL Forward Sequence</code></a> (and, preferrably,
|
||||
an <a href="../../../../libs/mpl/doc/refmanual/random-access-sequence.html">
|
||||
<code>MPL Random Access Sequence</code></a>) of index specifiers. For
|
||||
syntactic convenience, the
|
||||
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</a>
|
||||
of index specifiers. For syntactic convenience, the
|
||||
<a href="indices.html#indexed_by"><code>indexed_by</code></a>
|
||||
MPL sequence can be used.
|
||||
<li><code>Allocator</code> must comply with the C++ requirements for
|
||||
allocators <b>[lib.allocator.requirements]</b>.
|
||||
construct can be used.
|
||||
</li>
|
||||
<li><code>Allocator</code> must be an allocator of <code>Value</code> objects
|
||||
satisfying the associated C++ requirements at <b>[allocator.requirements]</b>.
|
||||
The following relaxations to the standard requirements are allowed:
|
||||
<ul>
|
||||
<li>Non-equal allocator instances are supported: swapping two non-equal
|
||||
instances must not throw any exception.
|
||||
</li>
|
||||
<li>For every type <code>T</code>,
|
||||
the type <code>Allocator::rebind<T>::other::pointer</code> can be any
|
||||
kind of random access iterator, provided that it is explicitly constructible from
|
||||
the literal <code>0</code> (standing here as the null pointer) or from any
|
||||
<code>p</code> of type <code>T*</code> pointing into an area allocated by
|
||||
some instance of <code>Allocator</code> or some other allocator type rebound
|
||||
from <code>Allocator</code>. A <code>pointer</code> constructed from
|
||||
<code>p</code> shall dereference to <code>*p</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<code>multi_index_container</code>s and all their iterators do not store references
|
||||
to allocated elements other than through the allocator's pointer type.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
Indices of a given <code>multi_index_container</code> instantiation cannot have
|
||||
duplicate <a href="indices.html#tags">tags</a>, either within a single
|
||||
index or in two different indices.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In what follows, the number of indices of the <code>multi_index_container</code>
|
||||
is named <code>I</code>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>ctor_args_list</code>
|
||||
@@ -524,9 +584,8 @@ implicit conversion from
|
||||
to <code>const ctor_args_list&</code>. This type is used for
|
||||
providing the construction arguments of the indices of the
|
||||
<code>multi_index_container</code>. <code>ctor_args_list</code> is
|
||||
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"><code>Default
|
||||
Constructible</code></a>, provided that all <code>ctor_args</code> types
|
||||
involved are default constructible.
|
||||
<code>DefaultConstructible</code>, provided that all <code>ctor_args</code> types
|
||||
involved are <code>DefaultConstructible</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>index_specifier_type_list</code>
|
||||
@@ -538,22 +597,16 @@ Same type as <code>IndexSpecifierList</code>.
|
||||
<code>index_type_list</code>
|
||||
|
||||
<blockquote>
|
||||
Model of
|
||||
<a href="../../../../libs/mpl/doc/refmanual/random-access-sequence.html">
|
||||
<code>MPL Random Access Sequence</code></a> and
|
||||
<a href="../../../../libs/mpl/doc/refmanual/extensible-sequence.html">
|
||||
<code>MPL Extensible Sequence</code></a> containing the types of the indices held by
|
||||
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</a>
|
||||
containing the types of the indices held by
|
||||
the <code>multi_index_container</code>, in the same order as they were specified.
|
||||
</blockquote>
|
||||
|
||||
<code>iterator_type_list</code>
|
||||
|
||||
<blockquote>
|
||||
Model of
|
||||
<a href="../../../../libs/mpl/doc/refmanual/random-access-sequence.html">
|
||||
<code>MPL Random Access Sequence</code></a> and
|
||||
<a href="../../../../libs/mpl/doc/refmanual/extensible-sequence.html">
|
||||
<code>MPL Extensible Sequence</code></a> containing the types of the iterators of
|
||||
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</a>
|
||||
containing the types of the iterators of
|
||||
the indices held by the <code>multi_index_container</code>, in the same order as they were
|
||||
specified.
|
||||
</blockquote>
|
||||
@@ -561,15 +614,28 @@ specified.
|
||||
<code>const_iterator_type_list</code>
|
||||
|
||||
<blockquote>
|
||||
Model of
|
||||
<a href="../../../../libs/mpl/doc/refmanual/random-access-sequence.html">
|
||||
<code>MPL Random Access Sequence</code></a> and
|
||||
<a href="../../../../libs/mpl/doc/refmanual/extensible-sequence.html">
|
||||
<code>MPL Extensible Sequence</code></a> containing the types of the constant
|
||||
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</a>
|
||||
containing the types of the constant
|
||||
iterators of the indices held by the <code>multi_index_container</code>, in the same order
|
||||
as they were specified.
|
||||
</blockquote>
|
||||
|
||||
<a name="node_type"><code>node_type</code></a>
|
||||
|
||||
<blockquote>
|
||||
Node handle class following the standard specification at
|
||||
<b>[container.node]</b> (version for set containers).
|
||||
Two instantiations of <code>multi_index_container</code>
|
||||
have compatible nodes (i.e., the same <code>node_type</code>) if and only if
|
||||
they are of the form
|
||||
<code>multi_index_container<Value,IndexSpecifierList1,Allocator></code> and
|
||||
<code>multi_index_container<Value,IndexSpecifierList2,Allocator></code>,
|
||||
have the same number <code>I</code> of index specifiers, and, for <code>i</code> =
|
||||
<code>0</code>, ... , <code>I-1</code>, the respective <code>i</code>-th index specifiers
|
||||
refer to the same <a href="indices.html#index_catalog">type of index</a>, regardless
|
||||
of unique/non-unique variants and particular configuration type arguments.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="nested_templates">Nested class templates</a></h4>
|
||||
|
||||
<code>template<int N> struct nth_index</code>
|
||||
@@ -578,14 +644,14 @@ as they were specified.
|
||||
<code>nth_index<N>::type</code> yields the type of the
|
||||
<code>N</code>-th (0-based) index held by the <code>multi_index_container</code>, in
|
||||
the same order as they were specified.<br>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>.
|
||||
<b>Requires:</b> <code>0 <= N < I-1</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> struct index</code>
|
||||
|
||||
<blockquote>
|
||||
<code>index<Tag>::type</code> yields the type of the index which
|
||||
has <code>Tag</code> as an associated <a href="indices.html#tags">tag type</a>.</br>
|
||||
has <code>Tag</code> as an associated <a href="indices.html#tags">tag type</a>.<br>
|
||||
<b>Requires:</b> Some index of the <code>multi_index_container</code> has <code>Tag</code>
|
||||
as an associated tag type.
|
||||
</blockquote>
|
||||
@@ -595,6 +661,7 @@ as an associated tag type.
|
||||
<blockquote>
|
||||
<code>nth_index_iterator<N>::type</code> is equivalent to
|
||||
<code>nth_index<N>::type::iterator</code>.<br>
|
||||
<b>Note:</b> The use of <code>nth_index_iterator</code> is deprecated.
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N> struct nth_index_const_iterator</code>
|
||||
@@ -602,6 +669,7 @@ as an associated tag type.
|
||||
<blockquote>
|
||||
<code>nth_index_const_iterator<N>::type</code> is equivalent to
|
||||
<code>nth_index<N>::type::const_iterator</code>.<br>
|
||||
<b>Note:</b> The use of <code>nth_index_const_iterator</code> is deprecated.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> struct index_iterator</code>
|
||||
@@ -609,6 +677,7 @@ as an associated tag type.
|
||||
<blockquote>
|
||||
<code>index_iterator<Tag>::type</code> is equivalent to
|
||||
<code>index<Tag>::type::iterator</code>.<br>
|
||||
<b>Note:</b> The use of <code>index_iterator</code> is deprecated.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> struct index_const_iterator</code>
|
||||
@@ -616,12 +685,21 @@ as an associated tag type.
|
||||
<blockquote>
|
||||
<code>index_const_iterator<Tag>::type</code> is equivalent to
|
||||
<code>index<Tag>::type::const_iterator</code>.<br>
|
||||
<b>Note:</b> The use of <code>index_const_iterator</code> is deprecated.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<code>multi_index_container();</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Constructs an empty <code>multi_index_container</code> using the
|
||||
default values of <code>ctor_args_list</code> and <code>allocator_type</code>.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<code>explicit multi_index_container(<br>
|
||||
const ctor_args_list& comp=ctor_args_list(),<br>
|
||||
const ctor_args_list& args_list,<br>
|
||||
const allocator_type& al=allocator_type());</code>
|
||||
|
||||
<blockquote>
|
||||
@@ -630,19 +708,27 @@ specified argument list and allocator.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<code>explicit multi_index_container(const allocator_type& al);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Constructs an empty <code>multi_index_container</code> using the
|
||||
specified allocator and the default value of <code>ctor_args_list</code>.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename InputIterator><br>
|
||||
multi_index_container(<br>
|
||||
InputIterator first,InputIterator last,<br>
|
||||
const ctor_args_list& comp=ctor_args_list(),<br>
|
||||
const ctor_args_list& args_list=ctor_args_list(),<br>
|
||||
const allocator_type& al=allocator_type());</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>Value</code> or a type convertible to <code>Value</code>.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<b>Effects:</b> Constructs and empty <code>multi_index_container</code> using the
|
||||
<b>Requires:</b> <code>InputIterator</code> is an input iterator.
|
||||
<code>Value</code> is
|
||||
<code>EmplaceConstructible</code> into <code>multi_index_container</code>
|
||||
from <code>*first</code>.
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b> Constructs an empty <code>multi_index_container</code> using the
|
||||
specified argument list and allocator and fills it with
|
||||
the elements in the range [<code>first</code>,<code>last</code>).
|
||||
Insertion of each element may or may not succeed depending
|
||||
@@ -651,19 +737,80 @@ on the acceptance by all the indices of the <code>multi_index_container</code>.<
|
||||
the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
</blockquote>
|
||||
|
||||
<code>multi_index_container(<br>
|
||||
std::initializer_list<Value> list,<br>
|
||||
const ctor_args_list& args_list=ctor_args_list(),<br>
|
||||
const allocator_type& al=allocator_type());</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Equivalent to
|
||||
<code>multi_index_container(list.begin(),list.end(),args_list,al)</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>multi_index_container(<br>
|
||||
const multi_index_container<Value,IndexSpecifierList,Allocator>& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Constructs a copy of <code>x</code>, copying its
|
||||
elements as well as its internal objects (key extractors, comparison objects,
|
||||
allocator.)<br>
|
||||
elements as well as its internal objects (those specified
|
||||
in <code>ctor_args_list</code> and the allocator).<br>
|
||||
<b>Postconditions:</b> <code>*this==x</code>. The order on every index
|
||||
of the <code>multi_index_container</code> is preserved as well.<br>
|
||||
<b>Complexity:</b> <code>O(x.size()*log(x.size()) + C(x.size()))</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>multi_index_container(<br>
|
||||
multi_index_container<Value,IndexSpecifierList,Allocator>&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Constructs a <code>multi_index_container</code> by transferring the
|
||||
elements of <code>x</code> and copying its internal objects (those specified
|
||||
in <code>ctor_args_list</code> and the allocator).<br>
|
||||
<b>Postconditions:</b> If <code>x==y</code> just
|
||||
before the movement, <code>*this==y</code>. The order on every index
|
||||
of the <code>multi_index_container</code> is preserved as well.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<code>multi_index_container(<br>
|
||||
const multi_index_container<Value,IndexSpecifierList,Allocator>& x,<br>
|
||||
const allocator_type& al);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Constructs a copy of <code>x</code>, copying its
|
||||
elements and its internal objects (those specified
|
||||
in <code>ctor_args_list</code>) and using a copy of the allocator
|
||||
<code>al</code> provided.<br>
|
||||
<b>Postconditions:</b> <code>*this==x</code>. The order on every index
|
||||
of the <code>multi_index_container</code> is preserved as well.<br>
|
||||
<b>Complexity:</b> <code>O(x.size()*log(x.size()) + C(x.size()))</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>multi_index_container(<br>
|
||||
multi_index_container<Value,IndexSpecifierList,Allocator>&& x,<br>
|
||||
const allocator_type& al);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Value</code> is <code>MoveInsertable</code> into
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Constructs a <code>multi_index_container</code> by transferring/moving
|
||||
the elements of <code>x</code>, copying its internal objects (those specified
|
||||
in <code>ctor_args_list</code>) and using a copy of the allocator
|
||||
<code>al</code> provided. If <code>x.get_allocator()==al</code>, elements are transferred
|
||||
(no constructions involved), otherwise they are move constructed from <code>x</code>.<br>
|
||||
<b>Postconditions:</b> If <code>x==y</code> just
|
||||
before the movement, <code>*this==y</code>. The order on every index
|
||||
of the <code>multi_index_container</code> is preserved as well.<br>
|
||||
<b>Complexity:</b> Constant if <code>x.get_allocator()==al</code>, otherwise
|
||||
<code>O(x.size()*log(x.size()) + C(x.size()))</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>~multi_index_container()</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Destroys the <code>multi_index_container</code> and all the elements
|
||||
contained. The order in which the elements are destroyed is not specified.<br>
|
||||
@@ -674,8 +821,14 @@ contained. The order in which the elements are destroyed is not specified.<br>
|
||||
const multi_index_container<Value,IndexSpecifierList,Allocator>& x);</code>
|
||||
|
||||
<blockquote>
|
||||
Replaces the elements and internal objects of the <code>multi_index_container</code>
|
||||
with copies from <code>x</code>.<br>
|
||||
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Replaces the elements and internal objects (those specified
|
||||
in <code>ctor_args_list</code>) of the <code>multi_index_container</code>
|
||||
with copies from <code>x</code>. The internal allocator is replaced with a
|
||||
copy of <code>x.get_allocator()</code> if and only if
|
||||
<code>std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value</code>
|
||||
is <code>true</code>.<br>
|
||||
<b>Postconditions:</b> <code>*this==x</code>. The order on every index
|
||||
of the <code>multi_index_container</code> is preserved as well.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
@@ -685,7 +838,53 @@ C(x.size()))</code>.<br>
|
||||
of the types of <code>ctor_args_list</code> do not throw.
|
||||
</blockquote>
|
||||
|
||||
<code>allocator_type get_allocator()const;</code>
|
||||
<code>multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(<br>
|
||||
multi_index_container<Value,IndexSpecifierList,Allocator>&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> If <code>std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value</code>
|
||||
is <code>true</code>, <code>Value</code> is <code>MoveInsertable</code> into
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Replaces the elements of <code>multi_index_container</code>
|
||||
with those of <code>x</code> or with copies move-constructed from those of <code>x</code>.
|
||||
Replaces the internal objects (those specified
|
||||
in <code>ctor_args_list</code>) with copies from the
|
||||
corresponding objects in <code>x</code>. Replaces the internal allocator with a
|
||||
copy of <code>x.get_allocator()</code> if and only if
|
||||
<code>std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value</code>
|
||||
is <code>true</code>.
|
||||
Elements of <code>x</code> are transferred (no constructions involved) if and only if
|
||||
<code>x.get_allocator()</code> is copied or is equal to the previous value of the internal
|
||||
allocator.
|
||||
<br>
|
||||
<b>Postconditions:</b> If <code>x==y</code> just
|
||||
before the movement, <code>*this==y</code>. The order on every index
|
||||
of the <code>multi_index_container</code> is preserved as well.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
<b>Complexity:</b> <code>O(n)</code> if elements of <code>x</code> are transferred,
|
||||
otherwise <code>O(n + x.size()*log(x.size()) + C(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> Strong, provided the copy and assignment operations
|
||||
of the types of <code>ctor_args_list</code> do not throw.
|
||||
</blockquote>
|
||||
|
||||
<code>multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(<br>
|
||||
std::initializer_list<Value> list);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Replaces the elements of the <code>multi_index_container</code>
|
||||
with copies of the elements of <code>list</code>, inserted in the specified order.
|
||||
Insertion of each element may or may not succeed depending
|
||||
on the acceptance by all the indices of the <code>multi_index_container</code>.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
<b>Complexity:</b> <code>O(n + I(m))</code>, where <code>m</code> is the
|
||||
number of elements of <code>list</code>.<br>
|
||||
<b>Exception safety:</b> Strong, provided the copy and assignment operations
|
||||
of the types of <code>ctor_args_list</code> do not throw.
|
||||
</blockquote>
|
||||
|
||||
<code>allocator_type get_allocator()const noexcept;</code>
|
||||
|
||||
<blockquote>
|
||||
Returns a copy of the <code>allocator_type</code> object used to construct
|
||||
@@ -695,27 +894,25 @@ the <code>multi_index_container</code>.<br>
|
||||
|
||||
<h4><a name="index_retrieval">Index retrieval operations</a></h4>
|
||||
|
||||
<code>template<int N> typename nth_index<N>::type& get();</code>
|
||||
<code>template<int N> typename nth_index<N>::type& get()noexcept;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>.<br>
|
||||
<b>Requires:</b> <code>0 <= N < I-1</code>.<br>
|
||||
<b>Effects:</b> Returns a reference to the
|
||||
<code>nth_index<N>::type</code> index held by <code>*this</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N> const typename nth_index<N>::type& get()const;</code>
|
||||
<code>template<int N> const typename nth_index<N>::type& get()const noexcept;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>.<br>
|
||||
<b>Requires:</b> <code>0 <= N < I-1</code>.<br>
|
||||
<b>Effects:</b> Returns a <code>const</code> reference to the
|
||||
<code>nth_index<N>::type</code> index held by <code>*this</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> typename index<Tag>::type& get()</code>
|
||||
<code>template<typename Tag> typename index<Tag>::type& get()noexcept;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that <code>index<Tag>::type</code>
|
||||
@@ -724,10 +921,9 @@ is valid.<br>
|
||||
<code>index<Tag>::type</code> index held by
|
||||
<code>*this</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> const typename index<Tag>::type& get()const;</code>
|
||||
<code>template<typename Tag> const typename index<Tag>::type& get()const noexcept;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that <code>index<Tag>::type</code>
|
||||
@@ -736,7 +932,6 @@ is valid.<br>
|
||||
<code>index<Tag>::type</code> index held by
|
||||
<code>*this</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="projection">Projection operations</a></h4>
|
||||
@@ -754,60 +949,60 @@ are <i>equivalent</i> if:
|
||||
</p>
|
||||
|
||||
<code>template<int N,typename IteratorType><br>
|
||||
typename nth_index_iterator<N>::type project(IteratorType it);</code>
|
||||
typename nth_index<N>::type::iterator project(IteratorType it);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>. <code>IteratorType</code>
|
||||
<b>Requires:</b> <code>0 <= N < I-1</code>. <code>IteratorType</code>
|
||||
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
iterator of some index of <code>*this</code> (i.e. does not refer to some
|
||||
other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>nth_index_iterator<N>::type</code> iterator
|
||||
other <code>multi_index_container</code>).<br>
|
||||
<b>Effects:</b> Returns an <code>nth_index<N>::type::iterator</code>
|
||||
equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N,typename IteratorType><br>
|
||||
typename nth_index_const_iterator<N>::type project(IteratorType it)const;</code>
|
||||
typename nth_index<N>::type::const_iterator project(IteratorType it)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>. <code>IteratorType</code>
|
||||
<b>Requires:</b> <code>0 <= N < I-1</code>. <code>IteratorType</code>
|
||||
belongs to <code>const_iterator_type_list</code> or
|
||||
<code>iterator_type_list</code>. <code>it</code> is a
|
||||
valid (constant or non-constant) iterator of some index of <code>*this</code>
|
||||
(i.e. does not refer to some other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>nth_index_const_iterator<N>::type</code>
|
||||
iterator equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag,typename IteratorType><br>
|
||||
typename index_iterator<Tag>::type project(IteratorType it);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that
|
||||
<code>index_iterator<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
iterator of some index of <code>*this</code> (i.e. does not refer to some
|
||||
other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>index_iterator<Tag>::type</code> iterator
|
||||
<b>Effects:</b> Returns an <code>nth_index<N>::type::const_iterator</code>
|
||||
equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag,typename IteratorType><br>
|
||||
typename index_const_iterator<Tag>::type project(IteratorType it)const;</code>
|
||||
typename index<Tag>::type::iterator project(IteratorType it);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that
|
||||
<code>index_const_iterator<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
<code>index<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
iterator of some index of <code>*this</code> (i.e. does not refer to some
|
||||
other <code>multi_index_container</code>).<br>
|
||||
<b>Effects:</b> Returns an <code>index<Tag>::type::iterator</code>
|
||||
equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag,typename IteratorType><br>
|
||||
typename index<Tag>::type::const_iterator project(IteratorType it)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that
|
||||
<code>index<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
belongs to <code>const_iterator_type_list</code> or
|
||||
<code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
(constant or non-constant) iterator of some index of <code>*this</code>
|
||||
(i.e. does not refer to some other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>index_const_iterator<Tag>::type</code>
|
||||
(i.e. does not refer to some other <code>multi_index_container</code>).<br>
|
||||
<b>Effects:</b> Returns an <code>index<Tag>::type::const_iterator</code>
|
||||
iterator equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
@@ -831,8 +1026,7 @@ these, the following concepts are used. A type <code>T</code> is <i>serializable
|
||||
archive (XML archive) and later retrieved from an input archive (XML archive) associated to
|
||||
the same storage. If <code>x'</code> of type <code>T</code> is loaded from the
|
||||
serialization information saved from another object <code>x</code>, we say that
|
||||
<code>x'</code> is a <i>restored copy</i> of <code>x</code>. Given a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html"><code>Binary Predicate</code></a>
|
||||
<code>x'</code> is a <i>restored copy</i> of <code>x</code>. Given a binary predicate
|
||||
<code>Pred</code> over (<code>T</code>, <code>T</code>), and objects <code>p</code>
|
||||
and <code>q</code> of type <code>Pred</code>, we say that <code>q</code>
|
||||
is <i>serialization-compatible</i> with <code>p</code> if
|
||||
@@ -849,7 +1043,7 @@ output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Value</code> is serializable (XML-serializable). Additionally,
|
||||
each of the indices of <code>m</code> can impose another requirements.<br>
|
||||
each of the indices of <code>m</code> can impose other requirements.<br>
|
||||
<b>Exception safety:</b> Strong with respect to <code>m</code>. If an exception
|
||||
is thrown, <code>ar</code> may be left in an inconsistent state.
|
||||
</blockquote>
|
||||
@@ -859,7 +1053,7 @@ input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Value</code> is serializable (XML-serializable). Additionally,
|
||||
each of the indices of <code>m'</code> can impose another requirements.<br>
|
||||
each of the indices of <code>m'</code> can impose other requirements.<br>
|
||||
<b>Exception safety:</b> Basic. If an exception is thrown, <code>ar</code> may be
|
||||
left in an inconsistent state.
|
||||
</blockquote>
|
||||
@@ -878,9 +1072,9 @@ Index reference
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 30th 2005</p>
|
||||
<p>Revised June 27th 2026</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2026 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Ordered indices reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="indices.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="hash_indices.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -17,8 +21,8 @@ Index reference
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
|
||||
Hashed indices
|
||||
<div class="next_link"><a href="rnk_indices.html"><img src="../next.gif" alt="ranked indices" border="0"><br>
|
||||
Ranked indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
@@ -38,7 +42,9 @@ Hashed indices
|
||||
<ul>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<li><a href="#instantiation_types">Instantiation types</a></li>
|
||||
<li><a href="#types">Nested types</a></li>
|
||||
<li><a href="#constructors">Constructors, copy and assignment</a></li>
|
||||
<li><a href="#iterators">Iterators</a></li>
|
||||
<li><a href="#modifiers">Modifiers</a></li>
|
||||
<li><a href="#observers">Observers</a></li>
|
||||
<li><a href="#set_operations">Set operations</a></li>
|
||||
@@ -92,6 +98,8 @@ their associated <a href="#ord_indices">ordered index</a> classes.
|
||||
<code>"boost/multi_index/ordered_index.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>initializer_list</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
@@ -159,7 +167,7 @@ two different forms, according to whether a tag list for the index is provided o
|
||||
|
||||
<p>
|
||||
If provided, <code>TagList</code> must be an instantiation of the class template
|
||||
<a href="#tag"><code>tag</code></a>.
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
The template arguments are used by the corresponding index implementation,
|
||||
refer to the <a href="#ord_indices">ordered indices</a> reference section for further
|
||||
explanations on their acceptable type values.
|
||||
@@ -185,15 +193,17 @@ together, with minor differences explicitly stated when they exist.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Except where noted, ordered indices (both unique and non-unique) are models of
|
||||
<a href="http://www.sgi.com/tech/stl/SortedAssociativeContainer.html">
|
||||
<code>Sorted Associative Container</code></a> and
|
||||
<a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html">
|
||||
<code>Unique Associative Container</code></a>, much as <code>std::set</code>s
|
||||
are. Accordingly, validity of iterators and references to elements is
|
||||
preserved. We only provide descriptions of those types and operations that are
|
||||
either not present in the concepts modeled or do not exactly conform to the
|
||||
requirements for these types of containers.
|
||||
Except where noted or if the corresponding interface does not exist,
|
||||
ordered indices (both unique and non-unique) satisfy the C++ requirements
|
||||
for associative containers at <b>[associative.reqmts]</b>
|
||||
(supporting unique and equivalent keys, respectively).
|
||||
Iterators (including to the end of the index) and pointers and references to an element
|
||||
remain valid during the lifetime of the associated container (which can change
|
||||
upon swapping), or until the referred-to element is erased or extracted;
|
||||
pointers and references to an extracted element, but not so for iterators,
|
||||
become valid again once the element is re-inserted.
|
||||
We only provide descriptions of those types and operations that
|
||||
do not exactly conform to or are not mandated by the standard requirements.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -201,7 +211,7 @@ requirements for these types of containers.
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span><span class=special>{</span> <b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=special>}</span> <span class=comment>// see range()</span>
|
||||
<b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=comment>// see range()</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
@@ -217,7 +227,8 @@ requirements for these types of containers.
|
||||
<span class=keyword>typedef</span> <span class=identifier>KeyFromValue</span> <span class=identifier>key_from_value</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Compare</span> <span class=identifier>key_compare</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>value_compare</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>tuple</span><span class=special><</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>></span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>></span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
|
||||
@@ -231,48 +242,85 @@ requirements for these types of containers.
|
||||
std::reverse_iterator<iterator></b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<const_iterator></b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>same as owning container </b><span class=identifier>node_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>following [container.insert.return] spec </b><span class=identifier>insert_return_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// construct/copy/destroy:</span>
|
||||
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special><</span><span class=identifier>value_type</span><span class=special>></span> <span class=identifier>list</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// iterators:</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>();</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>();</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>();</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>();</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// capacity:</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// modifiers:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&&...</span> <span class=identifier>args</span><span class=special>);</span>
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>emplace_hint</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&&...</span> <span class=identifier>args</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=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><</span><span class=identifier>value_type</span><span class=special>></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>&&</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>&&</span> <span class=identifier>nh</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
|
||||
<span class=identifier>node_type</span> <span class=identifier>extract</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>);</span>
|
||||
<span class=identifier>node_type</span> <span class=identifier>extract</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&</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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
|
||||
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>merge</span><span class=special>(</span>
|
||||
<span class=identifier>Index</span><span class=special>&&</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><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span>
|
||||
<span class=identifier>Index</span><span class=special>&&</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><</span><span class=identifier>Index</span><span class=special>>::</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><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// observers:</span>
|
||||
|
||||
<span class=identifier>key_from_value</span> <span class=identifier>key_extractor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -292,6 +340,11 @@ requirements for these types of containers.
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=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>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=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>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>lower_bound</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
@@ -390,9 +443,9 @@ section</a>. The complexity signature of ordered indices is:
|
||||
<ul>
|
||||
<li>copying: <code>c(n)=n*log(n)</code>,</li>
|
||||
<li>insertion: <code>i(n)=log(n)</code>,</li>
|
||||
<li>hinted insertion: <code>h(n)=1</code> (constant) if the hint element
|
||||
precedes the point of insertion, <code>h(n)=log(n)</code> otherwise,</li>
|
||||
<li>deletion: <code>d(n)=1</code> (constant),</li>
|
||||
<li>hinted insertion: <code>h(n)=1</code> (amortized constant) if the hint element
|
||||
is immediately after the point of insertion, <code>h(n)=log(n)</code> otherwise,</li>
|
||||
<li>deletion: <code>d(n)=1</code> (amortized constant),</li>
|
||||
<li>replacement: <code>r(n)=1</code> (constant) if the element position does not
|
||||
change, <code>r(n)=log(n)</code> otherwise,</li>
|
||||
<li>modifying: <code>m(n)=1</code> (constant) if the element position does not
|
||||
@@ -410,7 +463,7 @@ following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided),</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag<></code> is assumed),</li>
|
||||
<li><code>KeyFromValue</code> from the index specifier,</li>
|
||||
<li><code>Compare</code> from the index specifier.</li>
|
||||
</ul>
|
||||
@@ -419,11 +472,20 @@ following types:
|
||||
which determines the mechanism for extracting a key from <code>Value</code>,
|
||||
must be a model of <a href="key_extraction.html#key_extractors">
|
||||
<code>Key Extractor</code></a> from <code>Value</code>. <code>Compare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> on elements of
|
||||
<code>KeyFromValue::result_type</code>.
|
||||
<code>CopyConstructible</code> binary predicate inducing a strict weak order
|
||||
on elements of <code>KeyFromValue::result_type</code>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>iterator<br>
|
||||
const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types depend only on <code>node_type</code> and the position of
|
||||
the index in the <code>multi_index_container</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<p>
|
||||
@@ -444,11 +506,91 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="modifiers">Modifiers</a></h4>
|
||||
|
||||
<code>std::pair<iterator,bool> insert(const value_type& x);</code>
|
||||
<code><b>index class name</b>& operator=(std::initializer_list<value_type> list);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
where <code>a</code> is the <code>multi_index_container</code>
|
||||
object to which <code>*this</code> belongs.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="iterators">Iterators</a></h4>
|
||||
|
||||
<code>iterator iterator_to(const value_type& x);<br>
|
||||
const_iterator iterator_to(const value_type& x)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
|
||||
<b>Returns:</b> An iterator to <code>x</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="modifiers">Modifiers</a></h4>
|
||||
|
||||
<code>template<typename... Args><br>
|
||||
std::pair<iterator,bool> emplace(Args&&... args);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
|
||||
into <code>multi_index_container</code> from <code>args</code>.<br>
|
||||
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
|
||||
<code>std::forward<Args>(args)...</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful insertion,
|
||||
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename... Args><br>
|
||||
iterator emplace_hint(iterator position, Args&&... args);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
|
||||
into <code>multi_index_container</code> from <code>args</code>.
|
||||
<code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
|
||||
<code>std::forward<Args>(args)...</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<code>position</code> is used as a hint to improve the efficiency of the
|
||||
operation. If successful, insertion happens as close as possible to the
|
||||
location just prior to <code>position</code>.<br>
|
||||
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
|
||||
element. Otherwise, an iterator to an element that caused the insertion to be
|
||||
banned. Note that more than one element can be causing insertion not to be
|
||||
allowed.<br>
|
||||
<b>Complexity:</b> <code>O(H(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>std::pair<iterator,bool> insert(const value_type& x);</code><br>
|
||||
<code>std::pair<iterator,bool> insert(value_type&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
|
||||
into <code>multi_index_container</code>.<br>
|
||||
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
|
||||
into <code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
@@ -466,10 +608,16 @@ one element can be causing insertion not to be allowed.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator insert(iterator position,const value_type& x);</code>
|
||||
<code>iterator insert(iterator position,const value_type& x);</code><br>
|
||||
<code>iterator insert(iterator position,value_type&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
|
||||
into <code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
|
||||
into <code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
@@ -479,7 +627,8 @@ the index belongs if
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<code>position</code> is used as a hint to improve the efficiency of the
|
||||
operation.<br>
|
||||
operation. If successful, insertion happens as close as possible to the
|
||||
location just prior to <code>position</code>.<br>
|
||||
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
|
||||
element. Otherwise, an iterator to an element that caused the insertion to be
|
||||
banned. Note that more than one element can be causing insertion not to be
|
||||
@@ -492,30 +641,125 @@ allowed.<br>
|
||||
void insert(InputIterator first,InputIterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<b>Requires:</b> <code>InputIterator</code> is an input iterator.
|
||||
<code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
<code>multi_index_container</code> from <code>*first</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>iterator</span> <span class=identifier>hint</span><span class=special>=</span><span class=identifier>end</span><span class=special>();</span>
|
||||
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>hint</span><span class=special>=</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>hint</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
|
||||
</pre></blockquote>
|
||||
For each element of [<code>first</code>, <code>last</code>), in this
|
||||
order, inserts it into the <code>multi_index_container</code>
|
||||
to which this index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Complexity:</b> <code>O(m*H(n+m))</code>, where
|
||||
<code>m</code> is the number of elements in [<code>first</code>,
|
||||
<code>last</code>).<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>void erase(iterator position);</code>
|
||||
<code>void insert(std::initializer_list<value_type> list);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>())</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>insert_return_type insert(node_type&& nh);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>nh.empty() || get_allocator()==nh.get_allocator()</code>.<br>
|
||||
<b>Effects:</b> Does nothing if <code>nh</code> is empty; otherwise,
|
||||
inserts the node owned by <code>nh</code> into the
|
||||
<code>multi_index_container</code> to which the index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> <code>nh</code> is empty.<br>
|
||||
<b>Returns:</b> A value <code>p</code> of type <code>insert_return_type</code>.
|
||||
If <code>nh</code> is empty, <code>p.position</code> is <code>end()</code>,
|
||||
<code>p.inserted</code> is <code>false</code> and <code>p.node</code> is empty;
|
||||
on successful insertion, <code>p.position</code> points to the element inserted,
|
||||
<code>p.inserted</code> is <code>true</code> and <code>p.node</code>
|
||||
is empty;
|
||||
if the insertion failed, <code>p.position</code> points to an element that caused
|
||||
the insertion to be banned, <code>p.inserted</code> is <code>false</code> and
|
||||
<code>p.node</code> owns the original node.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong. If an exception
|
||||
is thrown, <code>nh</code> is not changed.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator insert(const_iterator position,node_type&& nh);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>nh.empty() || get_allocator()==nh.get_allocator()</code>.
|
||||
<code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Does nothing if <code>nh</code> is empty; otherwise,
|
||||
inserts the node owned by <code>nh</code> into the
|
||||
<code>multi_index_container</code> to which the index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<code>position</code> is used as a hint to improve the efficiency of the
|
||||
operation. If successful, insertion happens as close as possible to the
|
||||
location just prior to <code>position</code>.<br>
|
||||
<b>Postconditions:</b> <code>nh</code> is empty if insertion succeeds,
|
||||
and is not changed otherwise.<br>
|
||||
<b>Returns:</b> <code>end()</code> if <code>nh</code> is empty.
|
||||
On successful insertion, an iterator to the newly inserted
|
||||
element; otherwise, an iterator to an element that caused the insertion to be
|
||||
banned. Note that more than one element can be causing insertion not to be
|
||||
allowed.<br>
|
||||
<b>Complexity:</b> <code>O(H(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong. If an exception
|
||||
is thrown, <code>nh</code> is not changed.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>node_type extract(const_iterator position);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Extracts the node of the element pointed to by <code>position</code>.<br>
|
||||
<b>Returns:</b> A node handle owning the extracted node.<br>
|
||||
<b>Complexity:</b> <code>O(D(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>node_type extract(const key_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Extracts the node of the first element
|
||||
with key equivalent to <code>x</code>, if there is any.<br>
|
||||
<b>Returns:</b> A node handle owning the extracted node, or empty otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(log(n) + D(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator erase(iterator position);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Deletes the element pointed to by <code>position</code>.<br>
|
||||
<b>Returns:</b> An iterator pointing to the element immediately following
|
||||
the one that was deleted, or <code>end()</code>
|
||||
if no such element exists.<br>
|
||||
<b>Complexity:</b> <code>O(D(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
@@ -530,22 +774,26 @@ the number of elements deleted.<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>void erase(iterator first,iterator last);</code>
|
||||
<code>iterator erase(iterator first,iterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> [<code>first</code>,<code>last</code>) is a valid
|
||||
range of the index.<br>
|
||||
<b>Effects:</b> Deletes the elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Returns:</b> <code>last</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n) + m*D(n))</code>, where <code>m</code> is
|
||||
the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<a name="replace"><code>bool replace(iterator position,const value_type& x);</code></a>
|
||||
<a name="replace"><code>bool replace(iterator position,const value_type& x);</code></a><br>
|
||||
<code>bool replace(iterator position,value_type&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
|
||||
<code>position</code> is a valid dereferenceable iterator of the index.<br>
|
||||
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
|
||||
<code>position</code> is a valid dereferenceable iterator of the index.<br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
to by <code>position</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if, for the value <code>x</code>
|
||||
@@ -556,7 +804,8 @@ the index belongs if, for the value <code>x</code>
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved
|
||||
in all cases.<br>
|
||||
in all cases. If the key of the new value is equivalent to that of the
|
||||
replaced value, the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the replacement took place,
|
||||
<code>false</code> otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(R(n))</code>.<br>
|
||||
@@ -569,11 +818,14 @@ belongs remains in its original state.
|
||||
<code>template<typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Modifier</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<b>Requires:</b> <code>mod</code> is a unary function object
|
||||
accepting arguments of type
|
||||
<code>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
iterator of the index.
|
||||
The execution of <code>mod(e)</code>, where <code>e</code> is the element
|
||||
pointed to by <code>position</code>, does not invoke any operation of the
|
||||
<code>multi_index_container</code> after <code>e</code> is directly modified
|
||||
or, before modification, if the operation would invalidate <code>position</code>.<br>
|
||||
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
|
||||
pointed to by <code>position</code> and rearranges <code>*position</code> into
|
||||
all the indices of the <code>multi_index_container</code>. Rearrangement is successful if
|
||||
@@ -585,46 +837,182 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
|
||||
</ul>
|
||||
If the rearrangement fails, the element is erased.<br>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the
|
||||
operation succeeds.<br>
|
||||
operation succeeds. If the key of the modified value is equivalent to that of the
|
||||
original value, the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
<b>Exception safety:</b> Basic. If an exception is thrown by some
|
||||
user-provided operation (except possibly <code>mod</code>), then
|
||||
user-provided operation (including <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Modifier,typename Rollback><br>
|
||||
bool modify(iterator position,Modifier mod,Rollback back);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
|
||||
objects accepting arguments of type
|
||||
<code>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.
|
||||
The execution of <code>mod(e)</code>, where <code>e</code> is the element
|
||||
pointed to by <code>position</code>, does not invoke any operation of the
|
||||
<code>multi_index_container</code> after <code>e</code> is directly modified
|
||||
or, before modification, if the operation would invalidate <code>position</code>.
|
||||
<code>back(e)</code> does not invoke any operation of the
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
|
||||
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
|
||||
all the indices of the <code>multi_index_container</code>. Rearrangement is successful if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists
|
||||
with equivalent key,</li>
|
||||
<li>AND rearrangement is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
If the rearrangement fails, <code>back(e)</code> is invoked: if the resulting value
|
||||
of <code>e</code> is consistent with its original position and constraints in all
|
||||
indices, the element is kept, otherwise it is erased.<br>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
|
||||
the element is erased under the conditions described below.
|
||||
If the key of the modified value is equivalent to that of the
|
||||
original value, the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong, except if <code>mod</code> or <code>back</code> throw an
|
||||
exception or <code>back(e)</code> fails to properly restore the element or there is
|
||||
a throwing user-provided operation after invoking <code>back(e)</code>, in which cases
|
||||
the modified element is erased. If <code>back</code>
|
||||
throws inside the handling code executing after some other user-provided
|
||||
operation has thrown, it is the exception generated by <code>back</code> that
|
||||
is rethrown.
|
||||
</blockquote>
|
||||
|
||||
<a name="modify_key">
|
||||
<code>template<typename Modifier> bool modify_key(iterator position,Modifier mod);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>key_from_value</code> is a read/write
|
||||
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
|
||||
from <code>value_type</code>. <code>Modifier</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
from <code>value_type</code>. <code>mod</code> is a
|
||||
unary function object accepting arguments of type
|
||||
<code>key_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
<b>Effects:</b> Calls <code>mod(k)</code> where <code>k</code> is the key
|
||||
obtained by the internal <code>KeyFromValue</code> object of the index from
|
||||
the element pointed to by <code>position</code>, and rearranges
|
||||
<code>*position</code> into all the indices of the <code>multi_index_container</code>.
|
||||
Rearrangement is successful if
|
||||
iterator of the index.
|
||||
The execution of <code>mod(k)</code>, where <code>k</code> is the key of the element
|
||||
pointed to by <code>position</code>, does not invoke any operation of the
|
||||
<code>multi_index_container</code> after <code>k</code> is directly modified
|
||||
or, before modification, if the operation would invalidate <code>position</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>modify(position,mod')</code>,
|
||||
with <code>mod'</code> defined in such a way that
|
||||
<code>mod'(x)</code> is the same as <code>mod(key(x))</code>, where
|
||||
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Modifier,typename Rollback><br>
|
||||
bool modify_key(iterator position,Modifier mod,Rollback back);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>key_from_value</code> is a read/write
|
||||
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
|
||||
from <code>value_type</code>. <code>mod</code> and <code>back</code>
|
||||
are unary function objects accepting arguments of type
|
||||
<code>key_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.
|
||||
The execution of <code>mod(k)</code>, where <code>k</code> is the key of the element
|
||||
pointed to by <code>position</code>, does not invoke any operation of the
|
||||
<code>multi_index_container</code> after <code>k</code> is directly modified
|
||||
or, before modification, if the operation would invalidate <code>position</code>.
|
||||
<code>back(k)</code> does not invoke any operation of the
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>,
|
||||
with <code>mod'</code> and <code>back</code> defined in such a way that
|
||||
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
|
||||
<code>back'(x)</code> is the same as <code>back(key(x))</code>, where
|
||||
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
|
||||
</blockquote>
|
||||
|
||||
<a name="merge"><code>template<typename Index> void merge(Index&& 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<typename Index> std::pair<iterator,bool> merge(<br>
|
||||
Index&& x,typename std::remove_reference_t<Index>::const_iterator i);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.
|
||||
<code>i</code> is a valid dereferenceable iterator of <code>x</code>.<br>
|
||||
<b>Effects:</b> Does nothing if the source and destination containers are the same;
|
||||
otherwise, transfers the node of the element referred to by <code>i</code> into the
|
||||
<code>multi_index_container</code> to which the destination index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists
|
||||
with equivalent key,</li>
|
||||
<li>AND rearrangement is allowed by all other indices of the
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
If the rearrangement fails, the element is erased.<br>
|
||||
<b>Postconditions:</b>Validity of <code>position</code> is preserved if
|
||||
the operation succeeds.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
<b>Exception safety:</b> Basic. If an exception is thrown by some
|
||||
user-provided operation (except possibly <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
Note that no element is copied or destroyed in the process.<br>
|
||||
<b>Postconditions:</b> If transfer succeeds, for any index in the source container
|
||||
having the same <code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to <code>*i</code>
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if transfer took place or the source and destination
|
||||
containers are the same. If <code>p.second</code> is <code>true</code>,
|
||||
<code>p.first</code> points to <code>*i</code>; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> If the source and destination containers are the same,
|
||||
constant; otherwise, <code>O(I(n)+D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise strong.
|
||||
</blockquote>
|
||||
|
||||
<code>
|
||||
template<typename Index> void merge(<br>
|
||||
Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator first,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator last);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.
|
||||
[<code>first</code>,<code>last</code>) is a valid range of <code>x</code>.<br>
|
||||
<b>Effects:</b> Does nothing if the source and destination containers are the same;
|
||||
otherwise, for each node in [<code>first</code>,<code>last</code>), in this order,
|
||||
the node is transferred to the <code>multi_index_container</code> to which the
|
||||
destination index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
Note that no element is copied or destroyed in the process.<br>
|
||||
<b>Postconditions:</b> For any index in the source container having the same
|
||||
<code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to the transferred elements
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Complexity:</b> If the source and destination containers are the same,
|
||||
constant; otherwise, <code>O(m*(I(n+m)+D(x.size())))</code>, where
|
||||
<code>m</code> is the number of elements in [<code>first</code>,
|
||||
<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise basic.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="observers">Observers</a></h4>
|
||||
@@ -646,10 +1034,7 @@ the index.<br>
|
||||
|
||||
<p>
|
||||
Ordered indices provide the full lookup functionality required by
|
||||
<a href="http://www.sgi.com/tech/stl/SortedAssociativeContainer.html">
|
||||
<code>Sorted Associative Containers</code></a> and
|
||||
<a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html">
|
||||
<code>Unique Associative Containers</code></a>, namely <code>find</code>,
|
||||
<b>[associative.reqmts]</b>, namely <code>find</code>,
|
||||
<code>count</code>, <code>lower_bound</code>, <code>upper_bound</code>
|
||||
and <code>equal_range</code>. Additionally, these member functions are
|
||||
templatized to allow for non-standard arguments, so extending
|
||||
@@ -659,20 +1044,14 @@ concept.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> <code>Compare</code> over values
|
||||
of type <code>Key</code>. A pair of types (<code>CompatibleKey</code>,
|
||||
Consider a binary predicate <code>Compare</code> inducing a strict
|
||||
weak order over values of type <code>Key</code>. A pair of types (<code>CompatibleKey</code>,
|
||||
<code>CompatibleCompare</code>) is said to be a <i>compatible extension</i>
|
||||
of <code>Compare</code> if
|
||||
<ol>
|
||||
<li><code>CompatibleCompare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
|
||||
<code>Binary Predicate</code></a> over (<code>Key</code>,
|
||||
<li><code>CompatibleCompare</code> is a binary predicate over (<code>Key</code>,
|
||||
<code>CompatibleKey</code>),</li>
|
||||
<li><code>CompatibleCompare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
|
||||
<code>Binary Predicate</code></a> over (<code>CompatibleKey</code>,
|
||||
<li><code>CompatibleCompare</code> is a binary predicate over (<code>CompatibleKey</code>,
|
||||
<code>Key</code>),</li>
|
||||
<li>if <code>c_comp(ck,k1)</code> then <code>!c_comp(k1,ck)</code>,</li>
|
||||
<li>if <code>!c_comp(ck,k1)</code> and <code>!comp(k1,k2)</code> then
|
||||
@@ -707,7 +1086,7 @@ interpretations.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns a pointer to an element whose key is equivalent to
|
||||
<code>x</code>, or <code>end()</code> if such an element does not exist.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
@@ -719,19 +1098,19 @@ iterator find(const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns a pointer to an element whose key is equivalent to
|
||||
<code>x</code>, or <code>end()</code> if such an element does not exist.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey> size_type<br>
|
||||
count(const CompatibleKey& x)const;
|
||||
<code>template<typename CompatibleKey><br>
|
||||
size_type count(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n) + count(x))</code>.<br>
|
||||
</blockquote>
|
||||
@@ -742,18 +1121,40 @@ size_type count(const CompatibleKey& x,const CompatibleCompare& comp)con
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n) + count(x,comp))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
bool contains(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns <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<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
bool contains(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns <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<typename CompatibleKey><br>
|
||||
iterator lower_bound(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns an iterator pointing to the first element with
|
||||
key not less than <code>x</code>, or <code>end()</code> if such an element does
|
||||
not exist.<br>
|
||||
@@ -766,7 +1167,7 @@ iterator lower_bound(const CompatibleKey& x,const CompatibleCompare& com
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns an iterator pointing to the first element with
|
||||
key not less than <code>x</code>, or <code>end()</code> if such an element does
|
||||
not exist.<br>
|
||||
@@ -779,7 +1180,7 @@ iterator upper_bound(const CompatibleKey& x)const;
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns an iterator pointing to the first element with
|
||||
key greater than <code>x</code>, or <code>end()</code> if such an element does
|
||||
not exist.<br>
|
||||
@@ -792,7 +1193,7 @@ iterator upper_bound(const CompatibleKey& x,const CompatibleCompare& com
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns an iterator pointing to the first element with
|
||||
key greater than <code>x</code>, or <code>end()</code> if such an element does
|
||||
not exist.<br>
|
||||
@@ -806,19 +1207,19 @@ std::pair<iterator,iterator> equal_range(<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>make_pair(lower_bound(x),upper_bound(x))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
std::pair<iterator,iterator> equal_range(</br>
|
||||
std::pair<iterator,iterator> equal_range(<br>
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to
|
||||
<code>make_pair(lower_bound(x,comp),upper_bound(x,comp))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
@@ -835,15 +1236,11 @@ are modeled after the following concepts.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> <code>Compare</code> over values
|
||||
of type <code>Key</code>. A type <code>LowerBounder</code> is said to be
|
||||
Consider a binary predicate <code>Compare</code> inducing a strict
|
||||
weak order over values of type <code>Key</code>. A type <code>LowerBounder</code> is said to be
|
||||
a <i>lower bounder</i> of <code>Compare</code> if
|
||||
<ol>
|
||||
<li><code>LowerBounder</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/Predicate.html">
|
||||
<code>Predicate</code></a> over <code>Key</code>,</li>
|
||||
<li><code>LowerBounder</code> is a predicate over <code>Key</code>,</li>
|
||||
<li>if <code>lower(k1)</code> and <code>!comp(k2,k1)</code> then
|
||||
<code>lower(k2)</code>,</li>
|
||||
</ol>
|
||||
@@ -852,9 +1249,7 @@ for every <code>lower</code> of type <code>LowerBounder</code>,
|
||||
<code>k2</code> of type <code>Key</code>. Similarly, an <i>upper bounder</i>
|
||||
is a type <code>UpperBounder</code> such that
|
||||
<ol>
|
||||
<li><code>UpperBounder</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/Predicate.html">
|
||||
<code>Predicate</code></a> over <code>Key</code>,</li>
|
||||
<li><code>UpperBounder</code> is a predcate over <code>Key</code>,</li>
|
||||
<li>if <code>upper(k1)</code> and <code>!comp(k1,k2)</code> then
|
||||
<code>upper(k2)</code>,</li>
|
||||
</ol>
|
||||
@@ -870,7 +1265,7 @@ std::pair<iterator,iterator> range(<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>LowerBounder</code> and <code>UpperBounder</code> are
|
||||
a lower and upper bounder of <code>key_compare</code>, respectively.</br>
|
||||
a lower and upper bounder of <code>key_compare</code>, respectively.<br>
|
||||
<b>Effects:</b> Returns a pair of iterators pointing to the beginning and one
|
||||
past the end of the subsequence of elements satisfying <code>lower</code> and
|
||||
<code>upper</code> simultaneously. If no such elements exist, the iterators
|
||||
@@ -908,7 +1303,7 @@ input archive (XML archive) <code>ar</code>.
|
||||
<b>Requires:</b> Additionally to the general requirements, <code>value_comp()</code>
|
||||
must be serialization-compatible with <code>m.get<i>().value_comp()</code>,
|
||||
where <code>i</code> is the position of the ordered index in the container.<br>
|
||||
<b>Postconditions:</b> On succesful loading, each of the elements of
|
||||
<b>Postconditions:</b> On successful loading, each of the elements of
|
||||
[<code>begin()</code>, <code>end()</code>) is a restored copy of the corresponding
|
||||
element in [<code>m.get<i>().begin()</code>, <code>m.get<i>().end()</code>).
|
||||
</blockquote>
|
||||
@@ -925,11 +1320,11 @@ Operation: loading of an <code>iterator</code> or <code>const_iterator</code>
|
||||
<code>it'</code> from an input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Postconditions:</b> On succesful loading, if <code>it</code> was dereferenceable
|
||||
<b>Postconditions:</b> On successful loading, if <code>it</code> was dereferenceable
|
||||
then <code>*it'</code> is the restored copy of <code>*it</code>, otherwise
|
||||
<code>it'==end()</code>.<br>
|
||||
<b>Note:</b> It is allowed that <code>it</code> be a <code>const_iterator</code>
|
||||
and the restored <code>it'</code> an <code>iterator</code>, or viceversa.
|
||||
and the restored <code>it'</code> an <code>iterator</code>, or vice versa.
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
@@ -940,15 +1335,15 @@ Index reference
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
|
||||
Hashed indices
|
||||
<div class="next_link"><a href="rnk_indices.html"><img src="../next.gif" alt="ranked indices" border="0"><br>
|
||||
Ranked indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 7th 2005</p>
|
||||
<p>Revised February 5th 2022</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2022 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -0,0 +1,712 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Ranked indices reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="indices.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="hash_indices.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Ranked indices reference</h1>
|
||||
|
||||
<div class="prev_link"><a href="ord_indices.html"><img src="../prev.gif" alt="ordered_indices" border="0"><br>
|
||||
Ordered indices
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
|
||||
Hashed indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#rnk_index_fwd_synopsis">Header
|
||||
<code>"boost/multi_index/ranked_index_fwd.hpp"</code> synopsis</a></li>
|
||||
<li><a href="#synopsis">Header
|
||||
<code>"boost/multi_index/ranked_index.hpp"</code> synopsis</a>
|
||||
<ul>
|
||||
<li><a href="#unique_non_unique">
|
||||
Index specifiers <code>ranked_unique</code> and <code>ranked_non_unique</code>
|
||||
</a></li>
|
||||
<li><a href="#rnk_indices">Ranked indices</a>
|
||||
<ul>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<li><a href="#instantiation_types">Instantiation types</a></li>
|
||||
<li><a href="#types">Nested types</a></li>
|
||||
<li><a href="#set_operations">Set operations</a></li>
|
||||
<li><a href="#rank_operations">Rank operations</a></li>
|
||||
<li><a href="#serialization">Serialization</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a name="rnk_index_fwd_synopsis">Header
|
||||
<a href="../../../../boost/multi_index/ranked_index_fwd.hpp">
|
||||
<code>"boost/multi_index/ranked_index_fwd.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=comment>// index specifiers ranked_unique and ranked_non_unique</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult ranked_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ranked_unique</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult ranked_non_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ranked_non_unique</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// indices</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span> <span class=keyword>class</span> <b>index name is implementation defined</b><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>ranked_index_fwd.hpp</code> provides forward declarations for index specifiers
|
||||
<a href="#unique_non_unique"><code>ranked_unique</code> and <code>ranked_non_unique</code></a> and
|
||||
their associated <a href="#rnk_indices">ranked index</a> classes.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="synopsis">Header
|
||||
<a href="../../../../boost/multi_index/ranked_index.hpp">
|
||||
<code>"boost/multi_index/ranked_index.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>initializer_list</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=comment>// index specifiers ranked_unique and ranked_non_unique</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult ranked_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ranked_unique</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult ranked_non_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ranked_non_unique</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// indices</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span> <span class=keyword>class</span> <b>index class name implementation defined</b><span class=special>;</span>
|
||||
|
||||
<span class=comment>// index comparison:</span>
|
||||
|
||||
<span class=comment>// <b>OP</b> is any of ==,<,!=,>,>=,<=</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// index specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="unique_non_unique">
|
||||
Index specifiers <code>ranked_unique</code> and <code>ranked_non_unique</code>
|
||||
</a></h3>
|
||||
|
||||
<p>
|
||||
These <a href="indices.html#index_specification">index specifiers</a> allow
|
||||
for insertion of <a href="#rnk_indices">ranked indices</a> without and with
|
||||
allowance of duplicate elements, respectively. The syntax of <code>ranked_unique</code>
|
||||
and <code>ranked_non_unique</code> coincide, thus we describe them in a grouped manner.
|
||||
<code>ranked_unique</code> and <code>ranked_non_unique</code> can be instantiated in
|
||||
two different forms, according to whether a tag list for the index is provided or not:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>TagList</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
If provided, <code>TagList</code> must be an instantiation of the class template
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
The template arguments are used by the corresponding index implementation,
|
||||
refer to the <a href="#rnk_indices">ranked indices</a> reference section for further
|
||||
explanations on their acceptable type values.
|
||||
</p>
|
||||
|
||||
<h3><a name="rnk_indices">Ranked indices</a></h3>
|
||||
|
||||
<p>
|
||||
Ranked indices are a variation of <a href="ord_indices.html">ordered indices</a>
|
||||
providing additional capabilities for calculation of and access by rank; the <i>rank</i> of an element is the
|
||||
distance to it from the beginning of the index. Besides this extension, ranked indices replicate the
|
||||
public interface of ordered indices with the difference, complexity-wise, that
|
||||
<a href="#complexity_signature">hinted insertion</a> and <a href="#complexity_signature">deletion</a>
|
||||
are done in logarithmic rather than constant time. Also, execution times and memory consumption are
|
||||
expected to be poorer due to the internal bookkeeping needed to maintain rank-related information
|
||||
(an exception being <a href="#count"><code>count</code> operations</a>, which are actually faster).
|
||||
As with ordered indices, ranked indices can be unique (no duplicate elements are allowed)
|
||||
or non-unique: either version is associated to a different index specifier, but
|
||||
the interface of both index types is the same.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In what follows, we only describe the extra operations provided by ranked indices or those
|
||||
operations with improved performance: for the
|
||||
rest refer to the <a href="ord_indices.html#ord_indices">documentation</a> for ordered
|
||||
indices, bearing in mind the occasional differences in complexity.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=comment>// see range_rank()</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined: dependent on types Value, Allocator,
|
||||
TagList, KeyFromValue, Compare</b><span class=special>></span>
|
||||
<span class=keyword>class</span> <b>name is implementation defined</b>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>public</span><span class=special>:</span>
|
||||
<span class=comment>// types:</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span> <span class=identifier>key_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>KeyFromValue</span> <span class=identifier>key_from_value</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Compare</span> <span class=identifier>key_compare</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>value_compare</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>></span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>const_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>size_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>difference_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>pointer</span> <span class=identifier>pointer</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_pointer</span> <span class=identifier>const_pointer</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<iterator></b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<const_iterator></b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>same as owning container </b><span class=identifier>node_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>following [container.insert.return] spec </b><span class=identifier>insert_return_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// construct/copy/destroy:</span>
|
||||
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special><</span><span class=identifier>value_type</span><span class=special>></span> <span class=identifier>list</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// iterators:</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// capacity:</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// modifiers:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&&...</span> <span class=identifier>args</span><span class=special>);</span>
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>emplace_hint</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&&...</span> <span class=identifier>args</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=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><</span><span class=identifier>value_type</span><span class=special>></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>&&</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>&&</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>&</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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</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><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>merge</span><span class=special>(</span>
|
||||
<span class=identifier>Index</span><span class=special>&&</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><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span>
|
||||
<span class=identifier>Index</span><span class=special>&&</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><</span><span class=identifier>Index</span><span class=special>>::</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><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// observers:</span>
|
||||
|
||||
<span class=identifier>key_from_value</span> <span class=identifier>key_extractor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>key_compare</span> <span class=identifier>key_comp</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>value_compare</span> <span class=identifier>value_comp</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// set operations:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>find</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>find</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=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>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=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>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>lower_bound</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>lower_bound</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>upper_bound</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>upper_bound</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>></span> <span class=identifier>equal_range</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>></span> <span class=identifier>equal_range</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// range:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>LowerBounder</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>UpperBounder</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>></span> <span class=identifier>range</span><span class=special>(</span>
|
||||
<span class=identifier>LowerBounder</span> <span class=identifier>lower</span><span class=special>,</span><span class=identifier>UpperBounder</span> <span class=identifier>upper</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// rank operations:</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>nth</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>rank</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>find_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>find_rank</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>lower_bound_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>lower_bound_rank</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>upper_bound_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>upper_bound_rank</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>></span> <span class=identifier>equal_range_rank</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>></span> <span class=identifier>equal_range_rank</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>LowerBounder</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>UpperBounder</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>></span>
|
||||
<span class=identifier>range_rank</span><span class=special>(</span><span class=identifier>LowerBounder</span> <span class=identifier>lower</span><span class=special>,</span><span class=identifier>UpperBounder</span> <span class=identifier>upper</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=comment>// index comparison:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>==(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>size</span><span class=special>()==</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>size</span><span class=special>()&&</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>equal</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>begin</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special><(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>lexicographical_compare</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>!=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special>==</span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>>(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>y</span><span class=special><</span><span class=identifier>x</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>>=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special><</span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special><=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special>></span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// index specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h4><a name="complexity_signature">Complexity signature</a></h4>
|
||||
|
||||
<p>
|
||||
We follow the terminology described in the
|
||||
<a href="indices.html#complexity_signature">complexity signature
|
||||
section</a>. The complexity signature of ranked indices is:
|
||||
<ul>
|
||||
<li>copying: <code>c(n)=n*log(n)</code>,</li>
|
||||
<li>insertion: <code>i(n)=log(n)</code>,</li>
|
||||
<li>hinted insertion: <b><code>h(n)=log(n)</code></b>,</li>
|
||||
<li>deletion: <b><code>d(n)=log(n)</code></b> ,</li>
|
||||
<li>replacement: <code>r(n)=1</code> (constant) if the element position does not
|
||||
change, <code>r(n)=log(n)</code> otherwise,</li>
|
||||
<li>modifying: <code>m(n)=1</code> (constant) if the element position does not
|
||||
change, <code>m(n)=log(n)</code> otherwise.</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
These complexity guarantees are the same as those of
|
||||
<a href="ord_indices.html#complexity_signature">ordered indices</a>
|
||||
except for hinted insertion and deletion, which are <code>log(n)</code> here and amortized constant there.
|
||||
</p>
|
||||
|
||||
<h4><a name="instantiation_types">Instantiation types</a></h4>
|
||||
|
||||
<p>Ranked indices are instantiated internally to <code>multi_index_container</code> and
|
||||
specified by means of <a href="indices.html#indexed_by"><code>indexed_by</code></a>
|
||||
with <a href="#unique_non_unique"> index specifiers <code>ranked_unique</code>
|
||||
and <code>ranked_non_unique</code></a>. Instantiations are dependent on the
|
||||
following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag<></code> is assumed),</li>
|
||||
<li><code>KeyFromValue</code> from the index specifier,</li>
|
||||
<li><code>Compare</code> from the index specifier.</li>
|
||||
</ul>
|
||||
These types are subject to the same requirements as specified for
|
||||
<a href="ord_indices.html#instantiation_types">ordered indices</a>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>iterator<br>
|
||||
const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types depend only on <code>node_type</code> and the position of
|
||||
the index in the <code>multi_index_container</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="set_operations">Set operations</a></h4>
|
||||
|
||||
<p>
|
||||
See the documentation of ordered indices for an explanation of the notions of
|
||||
<a href="ord_indices.html#set_operations"><i>compatible extension</i> and
|
||||
<i>compatible key</i></a>, which are referred to below.
|
||||
</p>
|
||||
|
||||
<a name="count">
|
||||
<code>template<typename CompatibleKey><br>
|
||||
size_type count(const CompatibleKey& 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<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="rank_operations">Rank operations</a></h4>
|
||||
|
||||
<p>
|
||||
The <i>rank</i> of an iterator <code>it</code> of a given container <code>c</code> (and,
|
||||
by extension, of the element it points to if the iterator is dereferenceable)
|
||||
is <code>std::distance(c.begin(),it)</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
See the documentation of ordered indices for an explanation of the notions of
|
||||
<a href="ord_indices.html#set_operations"><i>compatible extension</i>,
|
||||
<i>compatible key</i></a>,
|
||||
<a href="ord_indices.html#range_operations"><i>lower bounder</i> and <i>upper bounder</i></a>, which are
|
||||
referred to below.
|
||||
</p>
|
||||
|
||||
<code>iterator nth(size_type n)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Returns an iterator with rank <code>n</code>,
|
||||
or <code>end()</code> if <code>n>=size()</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>size_type rank(iterator position)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Returns the rank of <code>position</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey> size_type find_rank(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>rank(find(k))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
size_type find_rank(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>rank(find(x,comp))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
size_type lower_bound_rank(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>rank(lower_bound(x))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
size_type lower_bound_rank(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>rank(lower_bound(x,comp))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
size_type upper_bound_rank(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>rank(upper_bound(x))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
size_type upper_bound_rank(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>rank(upper_bound(x,comp))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
std::pair<size_type,size_type> equal_range_rank(<br>
|
||||
const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>make_pair(lower_bound_rank(x),upper_bound_rank(x))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
std::pair<size_type,size_type> equal_range_rank(<br>
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to
|
||||
<code>make_pair(lower_bound_rank(x,comp),upper_bound_rank(x,comp))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename LowerBounder,typename UpperBounder><br>
|
||||
std::pair<size_type,size_type> range_rank(<br>
|
||||
LowerBounder lower,UpperBounder upper)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>LowerBounder</code> and <code>UpperBounder</code> are
|
||||
a lower and upper bounder of <code>key_compare</code>, respectively.<br>
|
||||
<b>Effects:</b> Equivalent to
|
||||
<blockquote><pre>
|
||||
<span class=keyword>auto</span> <span class=identifier>p</span><span class=special>=</span><span class=identifier>range</span><span class=special>(</span><span class=identifier>lower</span><span class=special>,</span><span class=identifier>upper</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>make_pair</span><span class=special>(</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>first</span><span class=special>),</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>second</span><span class=special>));</span>
|
||||
</pre></blockquote>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
<b>Variants:</b> In place of <code>lower</code> or <code>upper</code> (or both),
|
||||
the singular value <code>boost::multi_index::unbounded</code> can be
|
||||
provided. This acts as a predicate which all values of type <code>key_type</code>
|
||||
satisfy.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="serialization">Serialization</a></h4>
|
||||
|
||||
<p>
|
||||
The prerequisites and postconditions associated to serialization of
|
||||
<code>multi_index_container</code>s with ranked indices are exactly the same
|
||||
as those of <a href="ord_indices.html#serialization">ordered indices</a>.
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="ord_indices.html"><img src="../prev.gif" alt="ordered_indices" border="0"><br>
|
||||
Ordered indices
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
|
||||
Hashed indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 5th 2022</p>
|
||||
|
||||
<p>© Copyright 2003-2022 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,6 +5,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Sequenced indices reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="hash_indices.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="rnd_indices.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -17,8 +21,8 @@ Hashed indices
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="key_extraction.html"><img src="../next.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
<div class="next_link"><a href="rnd_indices.html"><img src="../next.gif" alt="random access indices" border="0"><br>
|
||||
Random access indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
@@ -36,11 +40,13 @@ Key extraction
|
||||
<ul>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<li><a href="#instantiation_types">Instantiation types</a></li>
|
||||
<li><a href="#types">Nested types</a></li>
|
||||
<li><a href="#constructors">Constructors, copy and assignment</a></li>
|
||||
<li><a href="#iterators">Iterators</a></li>
|
||||
<li><a href="#capacity">Capacity operations</a></li>
|
||||
<li><a href="#modifiers">Modifiers</a></li>
|
||||
<li><a href="#list_operations">List operations</a></li>
|
||||
<li><a href="#special_list_operations">Special list operations</a></li>
|
||||
<li><a href="#rearrange_operations">Rearrange operations</a></li>
|
||||
<li><a href="#serialization">Serialization</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -87,6 +93,8 @@ its associated <a href="#seq_indices">sequenced index</a> class.
|
||||
<code>"boost/multi_index/sequenced_index.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>initializer_list</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
@@ -146,33 +154,33 @@ sorted according to their order of insertion: this means that new elements
|
||||
inserted through a different index of the <code>multi_index_container</code> are appended
|
||||
to the end of the sequenced index. Additionally, the index allows for free
|
||||
reordering of elements in the same vein as <code>std::list</code> does.
|
||||
Iterators (including to the end of the index) and pointers and references to an element
|
||||
remain valid during the lifetime of the associated container (which can change
|
||||
upon swapping), or until the referred-to element is erased or extracted;
|
||||
pointers and references to an extracted element, but not so for iterators,
|
||||
become valid again once the element is re-inserted.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are a number of differences with respect to <code>std::lists</code>:
|
||||
Except where noted or if the corresponding interface does not exist, sequenced
|
||||
indices verify the same container requirements as <code>std::list</code>:
|
||||
we only provide descriptions of those types and operations that are either not
|
||||
present in <code>std::list</code> or behave differently. Some of the
|
||||
most important differences are:
|
||||
<ul>
|
||||
<li>Sequenced indices are not <a href="http://www.sgi.com/tech/stl/Assignable.html">
|
||||
<code>Assignable</code></a> (like any other index.)</li>
|
||||
<li>The complexity of some operations, notably insertion and deletion, differ
|
||||
from those of <code>std::list</code>.
|
||||
</li>
|
||||
<li>Unlike as in <code>std::list</code>, insertions into a sequenced index
|
||||
may fail due to clashings with other indices. This alters the semantics
|
||||
of the operations provided with respect to their analogues in
|
||||
<code>std::list</code>.
|
||||
</li>
|
||||
<li>Elements in a sequenced index are not mutable, and can only be changed
|
||||
by means of <a href="#replace"><code>replace</code></a> and
|
||||
in place by means of <a href="#replace"><code>replace</code></a> and
|
||||
<a href="#modify"><code>modify</code></a> member functions.
|
||||
</li>
|
||||
</ul>
|
||||
Having these restrictions into account, sequenced indices are models
|
||||
of <a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">
|
||||
<code>Reversible Container</code></a>,
|
||||
<a href="http://www.sgi.com/tech/stl/FrontInsertionSequence.html">
|
||||
<code>Front Insertion Sequence</code></a> and
|
||||
<a href="http://www.sgi.com/tech/stl/BackInsertionSequence.html">
|
||||
<code>Back Insertion Sequence</code></a>. We only provide descriptions
|
||||
of those types and operations that are that are either not present in the
|
||||
concepts modeled or do not exactly conform to the requirements for these
|
||||
types of containers.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -188,50 +196,63 @@ types of containers.
|
||||
<span class=keyword>public</span><span class=special>:</span>
|
||||
<span class=comment>// types:</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>node_type</span><span class=special>::</span><span class=identifier>value_type</span> <span class=identifier>value_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>allocator_type</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>allocator_type</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>const_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>size_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>ptrdiff_t</span> <span class=identifier>difference_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>size_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>difference_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>allocator_type</span><span class=special>::</span><span class=identifier>pointer</span> <span class=identifier>pointer</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>allocator_type</span><span class=special>::</span><span class=identifier>const_pointer</span> <span class=identifier>const_pointer</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<iterator></b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<const_iterator></b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>same as owning container </b><span class=identifier>node_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>following [container.insert.return] spec </b><span class=identifier>insert_return_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// construct/copy/destroy:</span>
|
||||
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special><</span><span class=identifier>value_type</span><span class=special>></span> <span class=identifier>list</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special><</span><span class=identifier>value_type</span><span class=special>></span> <span class=identifier>list</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>value</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// iterators:</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>();</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>();</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>();</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>();</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// capacity:</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>value_type</span><span class=special>());</span>
|
||||
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// access:</span>
|
||||
|
||||
@@ -240,32 +261,55 @@ types of containers.
|
||||
|
||||
<span class=comment>// modifiers:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>emplace_front</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&&...</span> <span class=identifier>args</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>push_front</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>push_front</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>pop_front</span><span class=special>();</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>emplace_back</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&&...</span> <span class=identifier>args</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>push_back</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>push_back</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>pop_back</span><span class=special>();</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&&...</span> <span class=identifier>args</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special><</span><span class=identifier>value_type</span><span class=special>></span> <span class=identifier>list</span><span class=special>);</span>
|
||||
<span class=identifier>insert_return_type</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>node_type</span><span class=special>&&</span> <span class=identifier>nh</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>node_type</span> <span class=identifier>extract</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
|
||||
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// list operations:</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></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>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>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>&&</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><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&&</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><</span><span class=identifier>Index</span><span class=special>>::</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><</span><span class=identifier>Index</span><span class=special>>::</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>&</span> <span class=identifier>value</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Predicate</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>remove_if</span><span class=special>(</span><span class=identifier>Predicate</span> <span class=identifier>pred</span><span class=special>);</span>
|
||||
@@ -280,12 +324,13 @@ types of containers.
|
||||
<span class=keyword>void</span> <span class=identifier>sort</span><span class=special>();</span>
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>sort</span><span class=special>(</span><span class=identifier>Compare</span> <span class=identifier>comp</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>reverse</span><span class=special>();</span>
|
||||
<span class=keyword>void</span> <span class=identifier>reverse</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// relocate operations:</span>
|
||||
<span class=comment>// rearrange operations:</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>relocate</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>relocate</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// index comparison:</span>
|
||||
@@ -376,12 +421,22 @@ index specifier. Instantiations are dependent on the following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided).</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag<></code> is assumed).</li>
|
||||
</ul>
|
||||
<code>TagList</code> must be an instantiation of
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>iterator<br>
|
||||
const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types depend only on <code>node_type</code> and the position of
|
||||
the index in the <code>multi_index_container</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<p>
|
||||
@@ -402,17 +457,22 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code><b>index class name</b>& operator=(std::initializer_list<value_type> list);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
where <code>a</code> is the <code>multi_index_container</code>
|
||||
object to which <code>*this</code> belongs.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template <class InputIterator><br>
|
||||
void assign(InputIterator first,InputIterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>clear</span><span class=special>();</span>
|
||||
@@ -420,6 +480,15 @@ index of the <code>multi_index_container</code> to which this index belongs.
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>void assign(std::initializer_list<value_type> list);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>assign</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>void assign(size_type n,const value_type& value);</code>
|
||||
|
||||
<blockquote>
|
||||
@@ -430,54 +499,127 @@ index of the <code>multi_index_container</code> to which this index belongs.
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="iterators">Iterators</a></h4>
|
||||
|
||||
<code>iterator iterator_to(const value_type& x);<br>
|
||||
const_iterator iterator_to(const value_type& x)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
|
||||
<b>Returns:</b> An iterator to <code>x</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="capacity">Capacity operations</a></h4>
|
||||
|
||||
<code>void resize(size_type n,const value_type& x=value_type());</code>
|
||||
<code>void resize(size_type n);<br>
|
||||
void resize(size_type n,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>></span><span class=identifier>size</span><span class=special>())</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>n</span><span class=special>-</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>else</span> <span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special><</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>n</span><span class=special>,</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
<b>Requires (first version):</b> <code>value_type</code> is <code>DefaultInsertable</code>
|
||||
into <code>multi_index_container</code>.<br>
|
||||
<b>Requires (second version):</b> <code>value_type</code> is <code>CopyInsertable</code>
|
||||
into <code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> If <code>size()<n</code>, tries to append <code>n-size()</code> default-inserted
|
||||
elements (first version) or copies of <code>x</code> (second version) at the end of
|
||||
the index. If <code>n<size()</code>, erases the last <code>size()-n</code> elements.<br>
|
||||
<b>Note:</b> If an expansion is requested, the size of the index is not guaranteed
|
||||
to be <code>n</code> after this operation (other indices may ban insertions.)
|
||||
to be <code>n</code> after this operation (other indices may ban insertions).
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="modifiers">Modifiers</a></h4>
|
||||
|
||||
<code>std::pair<iterator,bool> push_front(const value_type& x);</code>
|
||||
<code>template<typename... Args><br>
|
||||
std::pair<iterator,bool> emplace_front(Args&&... args);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Inserts <code>x</code> at the beginning of the sequence if
|
||||
no other index of the <code>multi_index_container</code> bans the insertion.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>emplace</span><span class=special>(</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>forward</span><span class=special><</span><span class=identifier>Args</span><span class=special>>(</span><span class=identifier>args</span><span class=special>)...);</span>
|
||||
</pre></blockquote>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful
|
||||
insertion, <code>p.first</code> points to the element inserted; otherwise,
|
||||
<code>p.first</code> points to an element that caused the insertion to be banned.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.
|
||||
</blockquote>
|
||||
|
||||
<code>std::pair<iterator,bool> push_back(const value_type& x);</code>
|
||||
|
||||
<code>std::pair<iterator,bool> push_front(const value_type& x);</code><br>
|
||||
<code>std::pair<iterator,bool> push_front(value_type&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Inserts <code>x</code> at the end of the sequence if
|
||||
no other index of the <code>multi_index_container</code> bans the insertion.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <span class=comment>// lvalue ref version</span>
|
||||
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>move</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
|
||||
</pre></blockquote>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful
|
||||
insertion, <code>p.first</code> points to the element inserted; otherwise,
|
||||
<code>p.first</code> points to an element that caused the insertion to be banned.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.
|
||||
</blockquote>
|
||||
|
||||
<code>std::pair<iterator,bool> insert(iterator position,const value_type& x);</code>
|
||||
<code>template<typename... Args><br>
|
||||
std::pair<iterator,bool> emplace_back(Args&&... args);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>emplace</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>forward</span><span class=special><</span><span class=identifier>Args</span><span class=special>>(</span><span class=identifier>args</span><span class=special>)...);</span>
|
||||
</pre></blockquote>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful
|
||||
insertion, <code>p.first</code> points to the element inserted; otherwise,
|
||||
<code>p.first</code> points to an element that caused the insertion to be banned.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>std::pair<iterator,bool> push_back(const value_type& x);</code><br>
|
||||
<code>std::pair<iterator,bool> push_back(value_type&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <span class=comment>// lvalue ref version</span>
|
||||
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>move</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
|
||||
</pre></blockquote>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful
|
||||
insertion, <code>p.first</code> points to the element inserted; otherwise,
|
||||
<code>p.first</code> points to an element that caused the insertion to be banned.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename... Args><br>
|
||||
std::pair<iterator,bool> emplace(iterator position,Args&&... args);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
|
||||
into <code>multi_index_container</code> from <code>args</code>.<br>
|
||||
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
|
||||
<code>std::forward<Args>(args)...</code> before <code>position</code> if insertion
|
||||
is allowed by all other indices of the <code>multi_index_container</code>.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful insertion,
|
||||
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>std::pair<iterator,bool> insert(iterator position,const value_type& x);</code><br>
|
||||
<code>std::pair<iterator,bool> insert(iterator position,value_type&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
|
||||
into <code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
|
||||
into <code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion
|
||||
is allowed by all other indices of the <code>multi_index_container</code>.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
@@ -492,7 +634,6 @@ Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<code>void insert(iterator position,size_type n,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>i</span><span class=special>=</span><span class=number>0</span><span class=special>;</span><span class=identifier>i</span><span class=special><</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span>
|
||||
@@ -504,27 +645,70 @@ void insert(iterator position,InputIterator first,InputIterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>InputIterator</code> is an input iterator.
|
||||
<code>value_type</code> is
|
||||
<code>EmplaceConstructible</code> into
|
||||
<code>multi_index_container</code> from <code>*first</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
|
||||
</pre></blockquote>
|
||||
For each element of [<code>first</code>, <code>last</code>), in this
|
||||
order, inserts it before <code>position</code> if insertion is allowed by all
|
||||
other indices of the <code>multi_index_container</code>.<br>
|
||||
<b>Complexity:</b> <code>O(m*I(n+m))</code>, where <code>m</code> is the
|
||||
number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> Basic.
|
||||
</blockquote>
|
||||
|
||||
<code>void insert(iterator position,std::initializer_list<value_type> list);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>insert_return_type insert(const_iterator position,node_type&& nh);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>nh.empty() || get_allocator()==nh.get_allocator()</code>.<br>
|
||||
<b>Effects:</b> Does nothing if <code>nh</code> is empty; otherwise,
|
||||
inserts the node owned by <code>nh</code> before <code>position</code> if insertion
|
||||
is allowed by all other indices of the <code>multi_index_container</code>.<br>
|
||||
<b>Postconditions:</b> <code>nh</code> is empty.<br>
|
||||
<b>Returns:</b> A value <code>p</code> of type <code>insert_return_type</code>.
|
||||
If <code>nh</code> is empty, <code>p.position</code> is <code>end()</code>,
|
||||
<code>p.inserted</code> is <code>false</code> and <code>p.node</code> is empty;
|
||||
on successful insertion, <code>p.position</code> points to the element inserted,
|
||||
<code>p.inserted</code> is <code>true</code> and <code>p.node</code>
|
||||
is empty;
|
||||
if the insertion failed, <code>p.position</code> points to an element that caused
|
||||
the insertion to be banned, <code>p.inserted</code> is <code>false</code> and
|
||||
<code>p.node</code> owns the original node.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong. If an exception
|
||||
is thrown, <code>nh</code> is not changed.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>node_type extract(const_iterator position);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Extracts the node of the element pointed to by <code>position</code>.<br>
|
||||
<b>Returns:</b> A node handle owning the extracted node.<br>
|
||||
<b>Complexity:</b> <code>O(D(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator erase(iterator position);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Deletes the element pointed to by <code>position</code>.<br>
|
||||
<b>Returns:</b> An iterator pointing to the element immediately following
|
||||
the one that was deleted, or <code>end()</code>
|
||||
@@ -545,11 +729,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<a name="replace"><code>bool replace(iterator position,const value_type& x);</code></a>
|
||||
<a name="replace"><code>bool replace(iterator position,const value_type& x);</code></a><br>
|
||||
<code>bool replace(iterator position,value_type&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
|
||||
<code>position</code> is a valid dereferenceable iterator of the index.<br>
|
||||
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
|
||||
<code>position</code> is a valid dereferenceable iterator of the index.<br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
to by <code>position</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if replacing is allowed by all other indices of the
|
||||
@@ -568,16 +755,19 @@ belongs remains in its original state.
|
||||
<code>template<typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Modifier</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<b>Requires:</b> <code>mod</code> is a unary function object
|
||||
accepting arguments of type
|
||||
<code>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
iterator of the index.
|
||||
The execution of <code>mod(e)</code>, where <code>e</code> is the element
|
||||
pointed to by <code>position</code>, does not invoke any operation of the
|
||||
<code>multi_index_container</code> after <code>e</code> is directly modified
|
||||
or, before modification, if the operation would invalidate <code>position</code>.<br>
|
||||
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
|
||||
pointed to by <code>position</code> and rearranges <code>*position</code> into
|
||||
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
|
||||
indices does not change the position of the element with respect to the index;
|
||||
rearrangement on other indices may or might not suceed. If the rearrangement
|
||||
rearrangement on other indices may or might not succeed. If the rearrangement
|
||||
fails, the element is erased.<br>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the
|
||||
operation succeeds.<br>
|
||||
@@ -585,70 +775,166 @@ operation succeeds.<br>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
<b>Exception safety:</b> Basic. If an exception is thrown by some
|
||||
user-provided operation (except possibly <code>mod</code>), then
|
||||
user-provided operation (including <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Modifier,typename Rollback><br>
|
||||
bool modify(iterator position,Modifier mod,Rollback back);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
|
||||
objects accepting arguments of type
|
||||
<code>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.
|
||||
The execution of <code>mod(e)</code>, where <code>e</code> is the element
|
||||
pointed to by <code>position</code>, does not invoke any operation of the
|
||||
<code>multi_index_container</code> after <code>e</code> is directly modified
|
||||
or, before modification, if the operation would invalidate <code>position</code>.
|
||||
<code>back(e)</code> does not invoke any operation of the
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
|
||||
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
|
||||
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
|
||||
indices does not change the position of the element with respect to the index;
|
||||
rearrangement on other indices may or might not succeed.
|
||||
If the rearrangement fails, <code>back(e)</code> is invoked: if the resulting value
|
||||
of <code>e</code> is consistent with its original position and constraints in all
|
||||
indices, the element is kept, otherwise it is erased.<br>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
|
||||
the element is erased under the conditions described below.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong, except if <code>mod</code> or <code>back</code> throw an
|
||||
exception or <code>back(e)</code> fails to properly restore the element or there is
|
||||
a throwing user-provided operation after invoking <code>back(e)</code>, in which cases
|
||||
the modified element is erased. If <code>back</code>
|
||||
throws inside the handling code executing after some other user-provided
|
||||
operation has thrown, it is the exception generated by <code>back</code> that
|
||||
is rethrown.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="list_operations">List operations</a></h4>
|
||||
|
||||
<p>
|
||||
Sequenced indices provides the full set of list operations provided by
|
||||
<code>std::list</code>; the semantics of these member functions, however,
|
||||
differ from that of <code>std::list</code> in some cases as insertions
|
||||
might not succeed due to banning by other indices. Similarly, the complexity
|
||||
Sequenced indices provide the full set of list operations found in
|
||||
<code>std::list</code>, extended in some cases such as <code>splice</code>;
|
||||
the semantics of these member functions, however,
|
||||
typically differs from that of <code>std::list</code> as insertions
|
||||
may not succeed due to banning by other indices. Similarly, the complexity
|
||||
of the operations may depend on the other indices belonging to the
|
||||
same <code>multi_index_container</code>.
|
||||
</p>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name</b>& x);</code>
|
||||
<a name="splice"><code>template<typename Index> void splice(const_iterator position,Index&& x);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>&x!=this</code>.</br>
|
||||
<b>Effects:</b> Inserts the contents of <code>x</code> before <code>position</code>,
|
||||
in the same order as they were in <code>x</code>. Those elements succesfully
|
||||
inserted are erased from <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
<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>& x,iterator i);</code>
|
||||
<code>
|
||||
template<typename Index> std::pair<iterator,bool> splice(<br>
|
||||
const_iterator position,Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator i);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>i</code> is a valid dereferenceable iterator <code>x</code>.<br>
|
||||
<b>Effects:</b> Inserts the element pointed to by <code>i</code> before
|
||||
<code>position</code>: if insertion is succesful, the element is erased from
|
||||
<code>x</code>. In the special case <code>&x==this</code>, no copy or
|
||||
deletion is performed, and the operation is always succesful. If
|
||||
<code>position==i</code>, no operation is performed.<br>
|
||||
<b>Postconditions:</b> If <code>&x==this</code>, no iterator or reference
|
||||
is invalidated.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(I(n) + D(n))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, strong.<br>
|
||||
<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&</b> x,iterator first,iterator last);</code>
|
||||
<code>
|
||||
template<typename Index> void splice(<br>
|
||||
const_iterator position,Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator first,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator last);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>first</code> and <code>last</code> are valid iterators of <code>x</code>.
|
||||
<code>last</code> is reachable from <code>first</code>. <code>position</code>
|
||||
is not in the range [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Effects:</b> For each element in the range [<code>first</code>,<code>last</code>),
|
||||
insertion is tried before <code>position</code>; if the operation is succesful,
|
||||
the element is erased from <code>x</code>. In the special case
|
||||
<code>&x==this</code>, no copy or deletion is performed, and insertions are
|
||||
always succesful.<br>
|
||||
<b>Postconditions:</b> If <code>&x==this</code>, no iterator or reference
|
||||
is invalidated.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(m*I(n+m) + m*D(x.size()))</code> where <code>m</code> is the number
|
||||
of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, basic.<br>
|
||||
<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>&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& value);</code>
|
||||
@@ -665,7 +951,7 @@ is the number of elements erased.<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Erases all elements <code>x</code> of the index for which
|
||||
<code>pred(x)</code> holds..<br>
|
||||
<code>pred(x)</code> holds.<br>
|
||||
<b>Complexity:</b> <code>O(n + m*D(n))</code>, where <code>m</code>
|
||||
is the number of elements erased.<br>
|
||||
<b>Exception safety:</b> Basic.
|
||||
@@ -697,44 +983,45 @@ is the number of elements erased.<br>
|
||||
<code>void merge(index class name& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>std::less<value_type></code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
|
||||
<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<value_type></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<value_type></code>.<br>
|
||||
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the
|
||||
corresponding position of the index (according to the order). Elements
|
||||
successfully inserted are erased from <code>x</code>. The resulting sequence
|
||||
<code>std::less<value_type></code>.<br>
|
||||
<b>Effects:</b> Attempts to splice every element of <code>x</code> into the
|
||||
corresponding position of the index (according to the order). The resulting sequence
|
||||
is stable, i.e. equivalent elements of either container preserve their
|
||||
relative position. In the special case <code>&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>&x==this</code>, constant; otherwise
|
||||
<code>O(n + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template <typename Compare> void merge(index class name& x,Compare comp);</code>
|
||||
<code>template <typename Compare> void merge(index class name& x,Compare comp);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Compare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
|
||||
<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>&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>&x==this</code>, constant; otherwise
|
||||
<code>O(n + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
@@ -744,24 +1031,22 @@ otherwise, basic.<br>
|
||||
<code>void sort();</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>std::less<value_type></code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
|
||||
<b>Requires:</b> <code>std::less<value_type></code> induces a
|
||||
strict weark ordering over <code>value_type</code>.<br>
|
||||
<b>Effects:</b> Sorts the index according to
|
||||
<code>std::less<value_type></code>. The sorting is stable, i.e.
|
||||
<code>std::less<value_type></code>. The sorting is stable, i.e.
|
||||
equivalent elements preserve their relative position.<br>
|
||||
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
|
||||
<b>Complexity:</b> <code>O(n*log(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code> if
|
||||
<code>std::less<value_type></code> does not throw; otherwise, basic.
|
||||
<code>std::less<value_type></code> does not throw; otherwise, basic.
|
||||
</blockquote>
|
||||
|
||||
<code>template <typename Compare> void sort(Compare comp);</code>
|
||||
<code>template <typename Compare> void sort(Compare comp);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Compare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
|
||||
<b>Requires:</b> <code>Compare</code> induces a
|
||||
strict weak ordering over <code>value_type</code>.<br>
|
||||
<b>Effects:</b> Sorts the index according to <code>comp</code>. The sorting
|
||||
is stable, i.e. equivalent elements preserve their relative position.<br>
|
||||
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
|
||||
@@ -770,23 +1055,21 @@ is stable, i.e. equivalent elements preserve their relative position.<br>
|
||||
not throw; otherwise, basic.
|
||||
</blockquote>
|
||||
|
||||
<code>void reverse();</code>
|
||||
<code>void reverse()noexcept;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Reverses the order of the elements in the index.<br>
|
||||
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
|
||||
<b>Complexity:</b> <code>O(n)</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="special_list_operations">Special list operations</a></h4>
|
||||
<h4><a name="rearrange_operations">Rearrange operations</a></h4>
|
||||
|
||||
<p>
|
||||
Sequenced indices provide some convenience member functions without
|
||||
counterparts in <code>std::list</code>. These operations are aimed at
|
||||
improving the usability of sequenced indices in points where
|
||||
the support offered by standard list operations is insufficient or
|
||||
difficult to use.
|
||||
These operations, without counterpart in <code>std::list</code>
|
||||
(although <code>splice</code> provides partially overlapping
|
||||
functionality), perform individual and global repositioning of elements
|
||||
inside the index.
|
||||
</p>
|
||||
|
||||
<code>void relocate(iterator position,iterator i);</code>
|
||||
@@ -816,6 +1099,20 @@ is repositioned just before <code>position</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<a name="rearrange"><code>template<typename InputIterator> void rearrange(InputIterator first);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> The range [<code>first</code>,
|
||||
<code>std::advance(first,n)</code>),
|
||||
where <code>n</code> is the size of the index, is a
|
||||
<a href="indices.html#views">free view</a> of the index.<br>
|
||||
<b>Effects:</b> The elements are rearranged so as to match the
|
||||
order of the previously described view.<br>
|
||||
<b>Postconditions:</b> No iterator or reference is invalidated.<br>
|
||||
<b>Complexity:</b> <code>O(n)</code>.<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="serialization">Serialization</a></h4>
|
||||
|
||||
<p>
|
||||
@@ -839,7 +1136,7 @@ input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> No additional requirements to those imposed by the container.<br>
|
||||
<b>Postconditions:</b> On succesful loading, each of the elements of
|
||||
<b>Postconditions:</b> On successful loading, each of the elements of
|
||||
[<code>begin()</code>, <code>end()</code>) is a restored copy of the corresponding
|
||||
element in [<code>m.get<i>().begin()</code>, <code>m.get<i>().end()</code>),
|
||||
where <code>i</code> is the position of the sequenced index in the container.
|
||||
@@ -857,11 +1154,11 @@ Operation: loading of an <code>iterator</code> or <code>const_iterator</code>
|
||||
<code>it'</code> from an input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Postconditions:</b> On succesful loading, if <code>it</code> was dereferenceable
|
||||
<b>Postconditions:</b> On successful loading, if <code>it</code> was dereferenceable
|
||||
then <code>*it'</code> is the restored copy of <code>*it</code>, otherwise
|
||||
<code>it'==end()</code>.<br>
|
||||
<b>Note:</b> It is allowed that <code>it</code> be a <code>const_iterator</code>
|
||||
and the restored <code>it'</code> an <code>iterator</code>, or viceversa.
|
||||
and the restored <code>it'</code> an <code>iterator</code>, or vice versa.
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
@@ -872,15 +1169,15 @@ Hashed indices
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="key_extraction.html"><img src="../next.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
<div class="next_link"><a href="rnd_indices.html"><img src="../next.gif" alt="random access indices" border="0"><br>
|
||||
Random access indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 7th 2005</p>
|
||||
<p>Revised August 30th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Release notes</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<link rel="start" href="index.html">
|
||||
<link rel="prev" href="future_work.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="acknowledgements.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -23,21 +27,811 @@ Acknowledgements
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#boost_1_92">Boost 1.92 release</a></li>
|
||||
<li><a href="#boost_1_91">Boost 1.91 release</a></li>
|
||||
<li><a href="#boost_1_85">Boost 1.85 release</a></li>
|
||||
<li><a href="#boost_1_84">Boost 1.84 release</a></li>
|
||||
<li><a href="#boost_1_83">Boost 1.83 release</a></li>
|
||||
<li><a href="#boost_1_82">Boost 1.82 release</a></li>
|
||||
<li><a href="#boost_1_81">Boost 1.81 release</a></li>
|
||||
<li><a href="#boost_1_80">Boost 1.80 release</a></li>
|
||||
<li><a href="#boost_1_79">Boost 1.79 release</a></li>
|
||||
<li><a href="#boost_1_78">Boost 1.78 release</a></li>
|
||||
<li><a href="#boost_1_77">Boost 1.77 release</a></li>
|
||||
<li><a href="#boost_1_74">Boost 1.74 release</a></li>
|
||||
<li><a href="#boost_1_73">Boost 1.73 release</a></li>
|
||||
<li><a href="#boost_1_71">Boost 1.71 release</a></li>
|
||||
<li><a href="#boost_1_70">Boost 1.70 release</a></li>
|
||||
<li><a href="#boost_1_69">Boost 1.69 release</a></li>
|
||||
<li><a href="#boost_1_68">Boost 1.68 release</a></li>
|
||||
<li><a href="#boost_1_67">Boost 1.67 release</a></li>
|
||||
<li><a href="#boost_1_66">Boost 1.66 release</a></li>
|
||||
<li><a href="#boost_1_64">Boost 1.64 release</a></li>
|
||||
<li><a href="#boost_1_62">Boost 1.62 release</a></li>
|
||||
<li><a href="#boost_1_60">Boost 1.60 release</a></li>
|
||||
<li><a href="#boost_1_59">Boost 1.59 release</a></li>
|
||||
<li><a href="#boost_1_58">Boost 1.58 release</a></li>
|
||||
<li><a href="#boost_1_57">Boost 1.57 release</a></li>
|
||||
<li><a href="#boost_1_56">Boost 1.56 release</a></li>
|
||||
<li><a href="#boost_1_55">Boost 1.55 release</a></li>
|
||||
<li><a href="#boost_1_54">Boost 1.54 release</a></li>
|
||||
<li><a href="#boost_1_49">Boost 1.49 release</a></li>
|
||||
<li><a href="#boost_1_48">Boost 1.48 release</a></li>
|
||||
<li><a href="#boost_1_47">Boost 1.47 release</a></li>
|
||||
<li><a href="#boost_1_44">Boost 1.44 release</a></li>
|
||||
<li><a href="#boost_1_43">Boost 1.43 release</a></li>
|
||||
<li><a href="#boost_1_42">Boost 1.42 release</a></li>
|
||||
<li><a href="#boost_1_41">Boost 1.41 release</a></li>
|
||||
<li><a href="#boost_1_38">Boost 1.38 release</a></li>
|
||||
<li><a href="#boost_1_37">Boost 1.37 release</a></li>
|
||||
<li><a href="#boost_1_36">Boost 1.36 release</a></li>
|
||||
<li><a href="#boost_1_35">Boost 1.35 release</a></li>
|
||||
<li><a href="#boost_1_34">Boost 1.34 release</a></li>
|
||||
<li><a href="#boost_1_33_1">Boost 1.33.1 release</a></li>
|
||||
<li><a href="#boost_1_33">Boost 1.33 release</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="boost_1_92">Boost 1.92 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fancy pointer support has been extended so that <code>multi_index_container</code>
|
||||
iterators now store references to the elements through the allocator's pointer type.
|
||||
In particular, this means that iterators can now be placed in shared memory using
|
||||
<a href="../../interprocess/index.html">Boost.Interprocess</a> allocators.
|
||||
</li>
|
||||
<li>Fixed a performance issue with hashed indices when rehashing at very large
|
||||
container sizes (<a href="https://github.com/boostorg/multi_index/pull/94">PR#94</a>).
|
||||
Contributed by Daniel Král.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_91">Boost 1.91 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li><b>Breaking change:</b> All type lists accepted or provided by the library (<code>indexed_by</code>,
|
||||
<code>tag</code>, nested typedefs <code>index_specifier_type_list</code>,
|
||||
<code>index_type_list</code>, <code>iterator_type_list</code> and
|
||||
<code>const_iterator_type_list</code>) are no longer based on
|
||||
<a href="../../mpl">Boost.MPL</a> but instead they are now
|
||||
<a href="../../mp11/doc/html/mp11.html#definitions">Boost.Mp11 lists</a>.
|
||||
As a result, Boost.MultiIndex doesn't depend anymore on Boost.MPL.
|
||||
It is expected that most user code won't be impacted by this
|
||||
change, but the previous behavior may be restored, however, by
|
||||
globally defining the macro
|
||||
<code>BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT</code>.
|
||||
Legacy support for Boost.MPL may be eventually deprecated and removed in the future.
|
||||
</li>
|
||||
<li><b>Breaking change:</b> <code>composite_key</code> and associated
|
||||
class templates (<code>composite_key_equal_to</code>, <code>composite_key_compare</code>,
|
||||
<code>composite_key_hash</code>) have been made variadic (previously the maximum
|
||||
number of template arguments was limited by <code>BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE</code>).
|
||||
This change should be transparent to users, with the exception that
|
||||
<code>composite_key::key_extractors</code> returns a <code>std::tuple</code>
|
||||
instead of a <code>boost::tuple</code> (and similarly for the rest of affected
|
||||
class templates).
|
||||
</li>
|
||||
<li>Removed internal workarounds and fallbacks to support pre-C++11 compilers.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_85">Boost 1.85 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed documentation errors.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_84">Boost 1.84 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed a serialization-related compile-time bug in old compilers
|
||||
without ADL support
|
||||
(<a href="https://github.com/boostorg/multi_index/issues/70">issue #70</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="boost_1_83">Boost 1.83 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Updated range <code>insert</code> in non-unique ordered indices to preserve insertion order
|
||||
of equivalent elements
|
||||
(<a href="https://github.com/boostorg/multi_index/issues/68">issue #68</a>).
|
||||
</li>
|
||||
<li>Serialization now uses <code>std::size_t</code> instead of <code>unsigned long</code>
|
||||
to save and load the size of a <code>multi_index_container</code>
|
||||
(<code>unsigned long</code> is smaller than <code>std::size_t</code> in LLP64 data models).
|
||||
<code>multi_index_container</code> serialization
|
||||
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
|
||||
bumped from 3 to 4 to reflect this change.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_82">Boost 1.82 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Serialization now uses <code>unsigned long</code> instead of
|
||||
<a href="../../serialization/doc/wrappers.html#collection_size_type"><code>collection_size_type</code></a>,
|
||||
and <code>multi_index_container</code> serialization
|
||||
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
|
||||
bumped from 2 to 3 to reflect this change.
|
||||
Reading old archives may fail for custom archive types giving special treatment to
|
||||
<code>collection_size_type</code> values: if this is the case, globally define
|
||||
the macro <code>BOOST_MULTI_INDEX_ENABLE_SERIALIZATION_COMPATIBILITY_V2</code>
|
||||
to ensure backwards compatibility in reading operations.
|
||||
</li>
|
||||
<li>Maintenance work.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_81">Boost 1.81 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Maintenance work.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_80">Boost 1.80 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Maintenance work.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_79">Boost 1.79 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Improved the efficiency of <code>count</code> operations in ranked indices from
|
||||
<code>O(log(n) + count)</code> to <code>O(log(n))</code>.
|
||||
Contributed by Damian Sawicki.
|
||||
</li>
|
||||
<li>Maintenance work.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_78">Boost 1.78 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Added <code>contains</code> to key-based indices
|
||||
(<a href="https://github.com/boostorg/multi_index/issues/35">issue #35</a>).
|
||||
</li>
|
||||
<li>Added <code>merge</code> operations to key-based indices. The functionality goes beyond
|
||||
the standard specification for (unordered) associative containers in a number of ways,
|
||||
most notably:
|
||||
<ul>
|
||||
<li>The source index can be of any type, including non key-based indices.</li>
|
||||
<li>Partial merge is provided: for instance, <code>x.merge(y,first,last)</code>
|
||||
merges only the elements of <code>y</code> within [<code>first</code>,<code>last</code>).
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Previous versions of <code>splice</code> for sequenced and random access indices
|
||||
were destructive, i.e. elements were copy-inserted into the destination and then erased
|
||||
from the source. Now, <code>splice</code> is based on node transfer much as <code>merge</code>
|
||||
in key-based indices, and has been similarly extended to accept source indices of any type:
|
||||
in fact, <code>splice</code> can be regarded as a frontend to the same functionality
|
||||
provided by <code>merge</code> in key-based indices. For reasons of backwards compatibility,
|
||||
the destructive behavior of <code>splice</code> has been retained in the case that the
|
||||
source and destination containers have unequal allocators.
|
||||
</li>
|
||||
<li>The fact has been documented that index iterator types do only depend on <code>node_type</code>
|
||||
and the position of the index in its <code>multi_index_container</code>,
|
||||
(except for hashed indices, where uniqueness/non-uniqueness is also a dependency). This has
|
||||
implications on the validity of iterators to elements transferred by <code>merge</code> or
|
||||
<code>splice</code>. This property is a variant of what has been called
|
||||
<a href="https://wg21.link/n2980">SCARY iterators</a> in the C++ standard mailing lists.
|
||||
SCARYness is currently (August 2021) not mandated for standard containers.
|
||||
</li>
|
||||
<li>Iterator SCARYness is now also preserved in <a href="tutorial/debug.html#safe_mode">safe mode</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_77">Boost 1.77 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Maintenance work.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_74">Boost 1.74 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
Added <a href="tutorial/indices.html#node_handling">node extraction and insertion</a>
|
||||
following the analogous interface of associative containers as introduced in C++17.
|
||||
This feature has also been extended to non key-based indices, in contrast to C++
|
||||
standard library sequence containers, which do not provide such functionality.
|
||||
</li>
|
||||
<li>Clarified documentation on read/write key extractors
|
||||
(<a href="https://github.com/boostorg/multi_index/issues/32">issue #32</a>).
|
||||
</li>
|
||||
<li>Maintenance work.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_73">Boost 1.73 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li><code>multi_index_container</code> is now
|
||||
<a href="https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer"><code>AllocatorAware</code></a>.
|
||||
</li>
|
||||
<li>Swapping of internal <code>KeyFromValue</code>, <code>Compare</code>, <code>Hash</code>
|
||||
and <code>Pred</code> objects now selects the appropriate <code>swap</code>
|
||||
function between <code>std::swap</code> and ADL candidates,
|
||||
in accordance with standard specifications in <b>[swappable.requirements]</b>
|
||||
(<a href="https://github.com/boostorg/multi_index/issues/29">issue #29</a>).
|
||||
</li>
|
||||
<li>Provided some internal copy constructors and assignment operators whose default
|
||||
implicit definition is deprecated in C++11 onwards (<b>[depr.impldec]</b>), which
|
||||
was warned about on some compilers.
|
||||
</li>
|
||||
<li>Maintenance work.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_71">Boost 1.71 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Added <a href="tutorial/key_extraction.html#x_mem_fun">variants of
|
||||
<code>const_mem_fun</code> and <code>mem_fun</code></a> for
|
||||
differently qualified member functions
|
||||
(<a href="https://github.com/boostorg/multi_index/issues/24">issue #24</a>).
|
||||
</li>
|
||||
<li>Terse <a href="reference/key_extraction.html#key">key</a> specification syntax
|
||||
now correctly handles <code>noexcept</code>-specified member functions
|
||||
(<a href="https://github.com/boostorg/multi_index/issues/24">issue #24</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_70">Boost 1.70 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li><code>size_type</code> and <code>difference_type</code> are now
|
||||
defined as the allocator's same-named types. This will not make any
|
||||
difference in the vast majority of cases, but allows for some degree
|
||||
of control of resulting internal structures via user-defined allocator
|
||||
types (see
|
||||
<a href="https://github.com/boostorg/multi_index/issues/17">issue #17</a>
|
||||
for motivation). For the moment being, this change is <i>not</i>
|
||||
documented in the reference section (i.e., it has semi-official status).
|
||||
</li>
|
||||
<li>Maintenance work.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_69">Boost 1.69 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Introduced an alternative
|
||||
<a href="tutorial/key_extraction.html#key">terse key specification syntax</a>
|
||||
for C++17 compliant environments.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_68">Boost 1.68 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Containers of moveable but non-copyable elements can now be serialized
|
||||
(ticket <a href="https://svn.boost.org/trac10/ticket/13478">#13478</a>).
|
||||
Thanks to Sébastien Paris for the report.
|
||||
</li>
|
||||
<li><code>multi_index_container</code>'s default constructor is no longer
|
||||
<code>explicit</code>
|
||||
(ticket <a href="https://svn.boost.org/trac10/ticket/13518">#13518</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_67">Boost 1.67 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Elements with overloaded <code>operator&</code> are now fully accepted
|
||||
(ticket <a href="https://svn.boost.org/trac10/ticket/13307">#13307</a>).
|
||||
Thanks to Daniel Frey for his updating
|
||||
<a href="../../utility/operators.htm#deref">Boost.Operators</a> to help
|
||||
fix this issue.
|
||||
</li>
|
||||
<li>Avoided usage of <code>std::allocator</code> members deprecated in C++17.
|
||||
Contributed by Daniela Engert.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_66">Boost 1.66 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Made <code>modify</code> and <code>modify_key</code> more robust so that
|
||||
the modified element is erased if the modifier throws or the rollback
|
||||
functor does not properly restore the element (full discussion at
|
||||
ticket <a href="https://svn.boost.org/trac/boost/ticket/12542">#12542</a>).
|
||||
This is technically backwards incompatible; for instance, the following code:
|
||||
<blockquote><pre>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>modify</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),[](</span><span class=keyword>auto</span><span class=special>&){</span><span class=keyword>throw</span> <span class=number>0</span><span class=special>;});</span>
|
||||
</pre></blockquote>
|
||||
keeps the container <code>c</code> untouched in former versions of Boost whereas
|
||||
now <code>c.begin()</code> is erased. Thanks to Jon Kalb for raising the issue.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_64">Boost 1.64 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed a bug related to ambiguous references in the presence of more than
|
||||
one ranked index
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/12955">#12955</a>).
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_62">Boost 1.62 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_60">Boost 1.60 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed an interoperability problem with <a href="http://www.qt.io/">Qt</a> due to the
|
||||
optional definition of a macro with name <code>foreach</code> in this framework.</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_59">Boost 1.59 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Added <a href="tutorial/indices.html#rnk_indices">ranked indices</a>.</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_58">Boost 1.58 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>The efficiency of lookup operations has improved in situations where they involve
|
||||
the generation of temporary values of <code>key_type</code>. Consider for instance
|
||||
the following code:
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>multi_t</span><span class=special>;</span>
|
||||
<span class=special>...</span>
|
||||
<span class=identifier>multi_t</span> <span class=identifier>m</span><span class=special>=...;</span>
|
||||
<span class=identifier>m</span><span class=special>.</span><span class=identifier>find</span><span class=special>(</span><span class=string>"boost"</span><span class=special>);</span> <span class=comment>// passed a const char*, not a std::string</span>
|
||||
</pre></blockquote>
|
||||
In previous versions of the library, the <code>find</code> operation generates
|
||||
several temporary <code>std::string</code>s (one every time an internal comparison is made).
|
||||
In sufficiently advanced compilers, this is now avoided so that only one temporary is
|
||||
created.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_57">Boost 1.57 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>When <code>std::tuple</code>s are available, these can be used for lookup operations
|
||||
in indices equipped with composite keys. <code>boost::tuple</code>s are also supported
|
||||
for backwards compatibility.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_56">Boost 1.56 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>The <code>erase(iterator)</code> member function of hashed indices
|
||||
used to have poor performance under low load conditions due to the requirement
|
||||
that an iterator to the next element must be returned (see ticket
|
||||
<a href="https://svn.boost.org/trac/boost/ticket/4264">#4264</a>). In accordance with
|
||||
the resolution of <a href="http://lwg.github.io/issues/lwg-closed.html#579">LWG
|
||||
issue #579</a>, this problem has been fixed while maintaining the interface of
|
||||
<code>erase</code>, at the expense of using one more
|
||||
word of memory per element. In fact, C++ complexity requirements on unordered
|
||||
associative containers have been improved for hashed indices so that
|
||||
<ul>
|
||||
<li>deletion of a given element is unconditionally constant-time,</li>
|
||||
<li>worst-case performance is not <code>O(n)</code> but <code>O(n<sub>dist</sub>)</code>,
|
||||
where <code>n<sub>dist</sub></code> is the number of non-equivalent elements in the index.
|
||||
</li>
|
||||
</ul>
|
||||
Due to the fact that hashed indices rely on a new data structure, the internal representation of
|
||||
their iterators and local iterators have changed, which affects serialization: their corresponding
|
||||
serialization <a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
|
||||
bumped from 0 to 1. Old archives involving hashed index (local) iterators can be loaded
|
||||
by Boost 1.56 version of Boost.MultiIndex, but not the other way around.
|
||||
</li>
|
||||
<li>Hashed indices now provide <code>reserve</code>.</li>
|
||||
<li>Hashed indices can now be checked for equality and inequality following the
|
||||
(suitably adapted) C++ standard specification in <b>[unord.req]</b>.</li>
|
||||
<li>The public interface of Boost.MultiIndex provide <code>noexcept</code> specifications
|
||||
where appropriate (for compliant compilers).
|
||||
</li>
|
||||
<li>Improved performance of failed insertions into a <code>multi_index_container</code>.</li>
|
||||
<li>Much internal code aimed at supporting MSVC++ 7.0 and prior has been removed.
|
||||
Compilation times without this legacy code might be slightly faster.
|
||||
</li>
|
||||
<li>Fixed a bug with insertion via iterators dereferencing to rvalues
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/9665">#9665</a>).
|
||||
</li>
|
||||
<li>Made Boost.MultiIndex compatible with <code>BOOST_BIND_NO_PLACEHOLDERS</code>
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/9798">#9798</a>).
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_55">Boost 1.55 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Boost.MultiIndex has been brought to a higher level of compliance
|
||||
with C++11.
|
||||
<ul>
|
||||
<li><code>multi_index_container</code> is now efficiently movable.</li>
|
||||
<li>Initializer lists supported.</li>
|
||||
<li>Emplace functions provided.</li>
|
||||
<li>Non-copyable elements (such as <code>std::unique_ptr<T></code>) supported. This includes
|
||||
insertion of a range [<code>first</code>,<code>last</code>) where the iterators point to a type that is
|
||||
convertible to that of the element: no copy construction happens in the process.
|
||||
</li>
|
||||
<li>Random access indices provide <code>shrink_to_fit()</code>.</li>
|
||||
</ul>
|
||||
Refer to the compiler specifics section for limitations
|
||||
on pre-C++11 compilers.
|
||||
</li>
|
||||
<li>The following classes are deprecated:
|
||||
<ul>
|
||||
<li><a href="reference/key_extraction.html#member_offset"><code>member_offset</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#const_mem_fun_explicit"><code>mem_fun_explicit</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_equal_to"><code>composite_key_result_equal_to</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_less"><code>composite_key_result_less</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_greater"><code>composite_key_result_greater</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_hash"><code>composite_key_result_hash</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_54">Boost 1.54 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Suppressed some potential warnings described in
|
||||
tickets <a href="https://svn.boost.org/trac/boost/ticket/8034">#8034</a> and <a href="https://svn.boost.org/trac/boost/ticket/8129">#8129</a>.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_49">Boost 1.49 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Suppressed a potential narrow conversion warning described in
|
||||
ticket <a href="https://svn.boost.org/trac/boost/ticket/3365">#3365</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_48">Boost 1.48 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed a compatibility problem with
|
||||
<a href="../../../doc/html/foreach.html">Boost.Foreach</a>
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/5741">#5741</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_47">Boost 1.47 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed an ADL problem in
|
||||
<a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>
|
||||
related with <a href="../../../doc/html/ref.html">Boost.Ref</a>.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_44">Boost 1.44 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
Fixed a bug preventing the use of <code>modify_key</code> with
|
||||
rollback in <a href="reference/ord_indices.html#modify_key">ordered</a> and
|
||||
<a href="reference/hash_indices.html#modify_key">hashed</a> indices when
|
||||
<code>Modifier</code> and <code>Rollback</code> are different types
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/4130">#4130</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_43">Boost 1.43 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="../../serialization/doc/serialization.html#constructors">Serialization
|
||||
of non default constructible values</a> is now properly supported
|
||||
through user-provided facilities <code>save_construct_data</code> and
|
||||
<code>load_construct_data</code>.
|
||||
<code>multi_index_container</code> serialization
|
||||
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
|
||||
bumped from 1 to 2.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_42">Boost 1.42 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_41">Boost 1.41 release</a></h2>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Serialization now uses the portable
|
||||
<a href="../../serialization/doc/wrappers.html#collection_size_type"><code>collection_size_type</code></a>
|
||||
type instead of the original <code>std::size_t</code> (ticket
|
||||
<a href="https://svn.boost.org/trac/boost/ticket/3365">#3365</a>).
|
||||
<code>multi_index_container</code> serialization
|
||||
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
|
||||
bumped from 0 to 1.
|
||||
</li>
|
||||
<li>Fixed a concurrency bug in the implementation of
|
||||
<a href="tutorial/debug.html#safe_mode">safe mode</a>
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/3462">#3462</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_38">Boost 1.38 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>These constructs are deprecated:
|
||||
<ul>
|
||||
<li><code>nth_index_iterator<MultiIndexContainer,N>::type</code>,</li>
|
||||
<li><code>multi_index_container<...>::nth_index_iterator<N>::type</code>,</li>
|
||||
<li><code>nth_index_const_iterator<MultiIndexContainer,N>::type</code>,</li>
|
||||
<li><code>multi_index_container<...>::nth_index_const_iterator<N>::type</code>,</li>
|
||||
<li><code>index_iterator<MultiIndexContainer,Tag>::type</code>,</li>
|
||||
<li><code>multi_index_container<...>::index_iterator<Tag>::type</code>,</li>
|
||||
<li><code>index_const_iterator<MultiIndexContainer,Tag>::type</code>,</li>
|
||||
<li><code>multi_index_container<...>::index_const_iterator<Tag>::type</code>.</li>
|
||||
</ul>
|
||||
Use the following instead:
|
||||
<ul>
|
||||
<li><code>nth_index<MultiIndexContainer,N>::type::iterator</code>,</li>
|
||||
<li><code>multi_index_container<...>::nth_index<N>::type::iterator</code>,</li>
|
||||
<li><code>nth_index<MultiIndexContainer,N>::type::const_iterator</code>,</li>
|
||||
<li><code>multi_index_container<...>::nth_index<N>::type::const_iterator</code>,</li>
|
||||
<li><code>index<MultiIndexContainer,Tag>::type::iterator</code>,</li>
|
||||
<li><code>multi_index_container<...>::index<Tag>::type::iterator</code>,</li>
|
||||
<li><code>index<MultiIndexContainer,Tag>::type::const_iterator</code>,</li>
|
||||
<li><code>multi_index_container<...>::index<Tag>::type::const_iterator</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_37">Boost 1.37 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_36">Boost 1.36 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li><a name="stable_update">On prior versions of the library, the <a href="tutorial/indices.html#hash_updating">update
|
||||
member functions</a> of hashed indices could alter the position of an element even if the
|
||||
associated key did not change with the update. This is legal but probably unexpected behavior.
|
||||
The functions have been rewritten to provide the additional guarantee that elements with
|
||||
unmodified key will not change position in hashed indices, just as always was the case with
|
||||
ordered indices. These guarantees are now documented in the reference.</a></li>
|
||||
<li>Added the constructor <code>multi_index_container::multi_index_container(const allocator_type&)</code>
|
||||
to mimic the equivalent interface in STL sequence containers.
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_35">Boost 1.35 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>New <a href="tutorial/key_extraction.html#global_fun"><code>global_fun</code></a>
|
||||
predefined key extractor.
|
||||
</li>
|
||||
<li>Added <a href="tutorial/indices.html#iterator_to"><code>iterator_to</code></a>
|
||||
facility.
|
||||
</li>
|
||||
<li>Included <a href="tutorial/creation.html#special_allocator">support for
|
||||
non-standard allocators</a> such as those of
|
||||
<a href="../../interprocess/index.html">Boost.Interprocess</a>, which makes
|
||||
<code>multi_index_container</code>s placeable in shared memory.
|
||||
</li>
|
||||
<li>New versions of <code>modify</code> and <code>modify_key</code> with
|
||||
rollback, as described in the
|
||||
<a href="tutorial/basics.html#ord_updating">tutorial</a>.
|
||||
</li>
|
||||
<li>Indices provide the new <code>cbegin</code>, <code>cend</code> and,
|
||||
when applicable, <code>crbegin</code> and <code>crend</code>
|
||||
member functions, in accordance with the latest drafts of the next
|
||||
revision of the C++ standard.
|
||||
</li>
|
||||
<li>Hinted insertion in ordered indices fully conforms to the resolutions of
|
||||
C++ Standard Library
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233">Defect
|
||||
Report 233</a>. The new requirement that the point of insertion
|
||||
be always as close as possible to the hint induces a different behavior than
|
||||
exhibited in former releases of Boost.MultiIndex, which can potentially cause
|
||||
backwards compatibility problems; in any case, the likelihood of these
|
||||
compatibility issues arising in a real scenario is very low.
|
||||
</li>
|
||||
<li>Sequenced and random access indices now follow the requirements of the
|
||||
C++ standard for sequence containers with respect to the operations
|
||||
<code>assign(f,l)</code> and <code>insert(p,f,l)</code> (23.1.1/9): if
|
||||
<code>f</code> and <code>l</code> are of the same integral type, the
|
||||
iterator-based overloads of these member functions are avoided:
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span><span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>sequenced_container</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=identifier>l</span><span class=special>(...);</span>
|
||||
<span class=identifier>sequenced_container</span> <span class=identifier>c</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// iterator-based overload of assign</span>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=identifier>l</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>l</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
|
||||
<span class=comment>// The following is equivalent to
|
||||
// c.assign(
|
||||
// static_cast<sequenced_container::size_type>(10),100);
|
||||
// that is, "10" and "100" are not taken to be iterators as
|
||||
// in the previous expression.</span>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=number>10</span><span class=special>,</span><span class=number>100</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
</li>
|
||||
<li>The performance of ordered indices <code>range</code> and
|
||||
<code>equal_range</code> has been improved.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_34">Boost 1.34 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Added <a href="tutorial/indices.html#rnd_indices">random access
|
||||
indices</a>.
|
||||
</li>
|
||||
<li>Non key-based indices provide new
|
||||
<a href="tutorial/indices.html#rearrange">rearrange facilities</a>
|
||||
allowing for interaction with external mutating algorithms.
|
||||
</li>
|
||||
<li>All predefined Boost.MultiIndex key extractors
|
||||
instantiated for a given type <code>T</code> can handle objects of types
|
||||
derived from or convertible to <code>T</code> (and
|
||||
<a href="reference/key_extraction.html#chained_pointers">chained pointers</a>
|
||||
to those). Previously, only objects of the exact type specified (along with
|
||||
<code>reference_wrapper</code>s and chained pointers to them) were accepted.
|
||||
</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>
|
||||
and related classes accept operands not included in tuples as if they were passed
|
||||
in a tuple of length 1; this allows the user to omit tuple enclosing in
|
||||
lookup operations involving composite keys when only the first key is provided.
|
||||
</li>
|
||||
<li>The core algorithms of ordered indices have been optimized, yielding
|
||||
an estimated reduction of about 5% in insertion times.
|
||||
</li>
|
||||
<li>Size of ordered indices node headers have been reduced by 25% on
|
||||
most platforms, using a well known
|
||||
<a href="tutorial/indices.html#ordered_node_compression">optimization
|
||||
technique</a>.
|
||||
</li>
|
||||
<li>The tutorial has been restructured, new examples added.</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_33_1">Boost 1.33.1 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>For ordered and hashed indices, <code>erase(it)</code> and
|
||||
<code>erase(first,last)</code> now return an iterator to the element
|
||||
following those being deleted (previously nothing was returned), in
|
||||
accordance with the C++ Standard Library
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">Defect
|
||||
Report 130</a> and issue 6.19 of TR1
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Issues
|
||||
List</a>.
|
||||
</li>
|
||||
<li>Boost.MultiIndex offers the usual guarantees with respect to
|
||||
multithreading code provided by most STL implementations:
|
||||
<ol>
|
||||
<li>Concurrent access to different containers is safe.</li>
|
||||
<li>Concurrent read-only access to the same container is safe.</li>
|
||||
</ol>
|
||||
In previous versions of the library, the latter guarantee was not properly
|
||||
maintained if the <a href="tutorial/debug.html#safe_mode">safe
|
||||
mode</a> was set. This problem has been fixed now.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_33">Boost 1.33 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Added <a href="advanced_topics.html#hashed_indices">hashed indices</a>,
|
||||
<li>Added <a href="tutorial/indices.html#hashed_indices">hashed indices</a>,
|
||||
whose interface is based on the specification for unordered associative
|
||||
containers by the C++ Standard Library Technical Report (TR1).
|
||||
<li>Added <a href="advanced_topics.html#serialization">serialization support</a>
|
||||
</li>
|
||||
<li>Added <a href="tutorial/creation.html#serialization">serialization support</a>
|
||||
for <a href="../../serialization/index.html">Boost.Serialization</a>.
|
||||
</li>
|
||||
<li>Destruction of <code>multi_index_container</code>s and <code>clear</code>
|
||||
@@ -48,8 +842,7 @@ Acknowledgements
|
||||
Boost 1.32 release. This results in much shorter and more readable error
|
||||
messages and has also a beneficial impact on compilers with strict limits on
|
||||
symbol name lengths. Additionally, a section on further
|
||||
<a href="compiler_specifics.html#symbol_reduction">reduction of symbol name
|
||||
lengths</a> has been added.
|
||||
reduction of symbol name lengths has been added.
|
||||
</li>
|
||||
<li>Restructured some parts of the documentation, new examples.</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
@@ -70,9 +863,9 @@ Acknowledgements
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised March 3rd 2005</p>
|
||||
<p>Revised June 27th 2026</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2026 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2004 Joaqu匤 M L�ez Mu�z.
|
||||
/* 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,6 +5,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Tests</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<link rel="start" href="index.html">
|
||||
<link rel="prev" href="examples.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="future_work.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -39,47 +43,57 @@ with some of the least common features offered by Boost.MultiIndex.
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_alloc_awareness.cpp"><code>test_alloc_awareness.cpp</code></a></td>
|
||||
<td>Checks <a href="https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer">allocator
|
||||
awareness</a>.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_basic.cpp"><code>test_basic.cpp</code></a></td>
|
||||
<td>Simple program along the lines of the employees example studied in the
|
||||
tutorial.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_capacity.cpp"><code>test_capacity.cpp</code></a></td>
|
||||
<td><code>empty</code>, <code>size</code> and (sequenced indices only)
|
||||
<code>resize</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_capacity.cpp"><code>test_capacity.cpp</code></a></td>
|
||||
<td><code>empty</code>, <code>size</code>, <code>resize</code>
|
||||
(non-key-based indices) and <code>reserve</code>/<code>capacity</code>
|
||||
(random access indices only).</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_comparison.cpp"><code>test_comparison.cpp</code></a></td>
|
||||
<td>Comparison between indices.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<tr>
|
||||
<td><a href="../test/test_composite_key.cpp"><code>test_composite_key.cpp</code></a></td>
|
||||
<td><code>composite_key</code> and <code>composite_key_compare</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_conv_iterators.cpp"><code>test_conv_iterators.cpp</code></a></td>
|
||||
<td>Checks convertibility of non-constant to constant iterators.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<tr>
|
||||
<td><a href="../test/test_copy_assignment.cpp"><code>test_copy_assignment.cpp</code></a></td>
|
||||
<td>Various forms of assignment: copy, <code>operator =</code>, insertion,
|
||||
(sequenced indices only) <code>assign</code> .
|
||||
(non key-based indices only) <code>assign</code>.
|
||||
</tr>
|
||||
<tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_hash_ops.cpp"><code>test_hash_ops.cpp</code></a></td>
|
||||
<td>Hashing operations.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<tr>
|
||||
<td><a href="../test/test_iterators.cpp"><code>test_iterators.cpp</code></a></td>
|
||||
<td>Constant and non-constant iterators and their reverse variants.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_key.cpp"><code>test_key.cpp</code></a></td>
|
||||
<td>Terse key specification syntax.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_key_extractors.cpp"><code>test_key_extractors.cpp</code></a></td>
|
||||
<td>Covers all use cases of key extractors shipped with the library.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_list_ops.cpp"><code>test_list_ops.cpp</code></a></td>
|
||||
<td>List-like operations particular to sequenced indices.</td>
|
||||
<td>List-like operations particular to sequenced and random access indices.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_modifiers.cpp"><code>test_modifiers.cpp</code></a></td>
|
||||
@@ -87,37 +101,46 @@ with some of the least common features offered by Boost.MultiIndex.
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_mpl_ops.cpp"><code>test_mpl_ops.cpp</code></a></td>
|
||||
<td>Metaprogramming manipulations of <code>multi_index_container</code> types.</td>
|
||||
<td>Boost.MPL interoperability (when <code> BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT</code> is enabled).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_node_handling.cpp"><code>test_node_handling.cpp</code></a></td>
|
||||
<td>Operations involving node extraction and insertion.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_observers.cpp"><code>test_observers.cpp</code></a></td>
|
||||
<td>Checks observer member functions of ordered and hashed indices.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<tr>
|
||||
<td><a href="../test/test_projection.cpp"><code>test_projection.cpp</code></a></td>
|
||||
<td>Projection of iterators among indices.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_range.cpp"><code>test_range.cpp</code></a></td>
|
||||
<td>Exercises the <code>range</code> facility (ordered indices only).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_rank_ops.cpp"><code>test_rank_ops.cpp</code></a></td>
|
||||
<td>Specific operations of ranked indices.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_rearrange.cpp"><code>test_rearrange.cpp</code></a></td>
|
||||
<td>Rearrange functions of sequenced and random access indices.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_safe_mode.cpp"><code>test_safe_mode.cpp</code></a></td>
|
||||
<td>Comprehensive coverage of all conditions checked in safe mode.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_serialization.cpp"><code>test_serialization.cpp</code></a></td>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_serialization1.cpp"><code>test_serialization1.cpp</code></a><br>
|
||||
<a href="../test/test_serialization2.cpp"><code>test_serialization2.cpp</code></a><br>
|
||||
<a href="../test/test_serialization3.cpp"><code>test_serialization3.cpp</code></a></td>
|
||||
<td>Serialization support.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<tr>
|
||||
<td><a href="../test/test_set_ops.cpp"><code>test_set_ops.cpp</code></a></td>
|
||||
<td>Set-like operations particular to ordered indices.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_special_list_ops.cpp"><code>test_special_list_ops.cpp</code></a></td>
|
||||
<td>Convenience functions of sequenced indices not present in
|
||||
<code>std::list</code>.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_special_set_ops.cpp"><code>test_special_set_ops.cpp</code></a></td>
|
||||
<td>Checks special lookup operations using compatible sorting criteria.</td>
|
||||
@@ -143,10 +166,9 @@ Future work
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised October 26th 2025</p>
|
||||
|
||||
<p>Revised July 27th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2025 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -3,22 +3,26 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Tutorial</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<title>Boost.MultiIndex Documentation - Tutorial - Basics</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="index.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="indices.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Tutorial</h1>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Basics</h1>
|
||||
|
||||
<div class="prev_link"><a href="index.html"><img src="prev.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
<div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="advanced_topics.html"><img src="next.gif" alt="advanced topics" border="0"><br>
|
||||
Advanced topics
|
||||
<div class="next_link"><a href="indices.html"><img src="../next.gif" alt="index types" border="0"><br>
|
||||
Index types
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
@@ -26,16 +30,15 @@ Advanced topics
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#rationale">Rationale</a></li>
|
||||
<li><a href="#namespace">Namespace</a></li>
|
||||
<li><a href="#intro">Introduction</a>
|
||||
<ul>
|
||||
<li><a href="#multipe_sort">Multiple sorts on a single set</a></li>
|
||||
<li><a href="#multiple_sort">Multiple sorts on a single set</a></li>
|
||||
<li><a href="#list_fast_lookup">A bidirectional list with fast lookup</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#index_spec">Index specification</a></li>
|
||||
<li><a href="#tagging">Tagging</a></li>
|
||||
<li><a href="#iterator_access">Iterator access</a></li>
|
||||
<li><a href="#index_types">Index types</a>
|
||||
<ul>
|
||||
<li><a href="#ord_indices">Ordered indices</a>
|
||||
@@ -62,78 +65,6 @@ Advanced topics
|
||||
<li><a href="#complexity">Complexity and exception safety</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="rationale">Rationale</a></h2>
|
||||
|
||||
<p>
|
||||
STL containers are designed around the concept that each container controls its
|
||||
own collection of elements, giving access to them in a manner specified by the
|
||||
container's type: so, an <code>std::set</code> maintains the elements ordered
|
||||
by a specified sorting criterium, <code>std::list</code> allows for free
|
||||
positioning of elements along a linear sequence, and so on.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sometimes, the necessity arises of having different access interfaces
|
||||
to the same underlying collection: for instance, some data might need to be
|
||||
sorted according to more than one comparison predicate, or a bidirectional list
|
||||
might benefit from a supplemental logarithmic lookup interface. In these
|
||||
situations, programmers typically resort to manual compositions of different
|
||||
containers, a solution that generally involves a fair amount of code
|
||||
devoted to preserve the synchronization of the different parts of
|
||||
the composition. Boost.MultiIndex allows for the specification of
|
||||
<code>multi_index_container</code>s comprised of one or more <i>indices</i> with
|
||||
different interfaces to the same collection of elements. The resulting constructs
|
||||
are conceptually cleaner than manual compositions, and often perform much better.
|
||||
An important design decision has been taken that the indices of a given
|
||||
<code>multi_index_container</code> instantiation be specified at compile time: this
|
||||
gives ample room for static type checking and code optimization.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex takes inspiration from basic concepts of indexing arising in the
|
||||
theory of relational databases, though it is not intended to provide a full-fledged
|
||||
relational database framework. <code>multi_index_container</code> integrates seamlessly
|
||||
into the STL container/algorithm design, and features some extra capabilities regarding
|
||||
lookup operations and element updating which are useful extensions even for
|
||||
single-indexed containers.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="multi_index_cont_example.png"
|
||||
alt="diagram of a multi_index_container with three indices"
|
||||
width="600" height="304"><br>
|
||||
<b>Fig. 1: Diagram of a <code>multi_index_container</code> with three indices.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The figure above depicts a <code>multi_index_container</code> composed of three indices:
|
||||
the first two present a set-like interface to the elements sorted by
|
||||
shape and id, respectively, while the latter index provides the functionality
|
||||
of a bidirectional list in the spirit of <code>std::list</code>. These
|
||||
indices act as "views" to the internal collection of elements, but they do not only
|
||||
provide read access to the set: insertion/deletion methods are also implemented much
|
||||
as those of <code>std::set</code>s or <code>std::list</code>s. Insertion of an
|
||||
element through one given index will only succeed if the uniqueness constraints of all
|
||||
indices are met.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="namespace">Namespace</a>
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
All the types of Boost.MultiIndex reside in namespace <code>::boost::multi_index</code>.
|
||||
Additionaly, the main class template <code>multi_index_container</code> and global functions
|
||||
<code>get</code> and <code>project</code> are lifted to namespace <code>::boost</code>
|
||||
by means of <code>using</code> declarations. For brevity of exposition, the fragments
|
||||
of code in the documentation are written as if the following declarations were in effect:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>using</span> <span class=keyword>namespace</span> <span class=special>::</span><span class=identifier>boost</span><span class=special>;</span>
|
||||
<span class=keyword>using</span> <span class=keyword>namespace</span> <span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h2><a name="intro">Introduction</a></h2>
|
||||
|
||||
<p>
|
||||
@@ -141,13 +72,13 @@ We introduce the main concepts of Boost.MultiIndex through the study of
|
||||
two typical use cases.
|
||||
</p>
|
||||
|
||||
<h3><a name="multipe_sort">Multiple sorts on a single set</a></h3>
|
||||
<h3><a name="multiple_sort">Multiple sorts on a single set</a></h3>
|
||||
|
||||
<p>
|
||||
STL sets and multisets are varying-length containers where elements are efficiently
|
||||
sorted according to a given comparison predicate. These container classes fall short
|
||||
of functionality when the programmer wishes to efficiently sort and look up the elements
|
||||
following a different sorting criterium. Consider for instance:
|
||||
following a different sorting criterion. Consider for instance:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -183,7 +114,7 @@ construct easily becomes unmaintainable.
|
||||
<p>
|
||||
Boost.MultiIndex features <a href="#ord_indices"><i>ordered indices</i></a>, which
|
||||
sort the elements according to a particular key, and are designed to help programmers
|
||||
in need of sequences of elements for which <i>more than one</i> sorting criteria are
|
||||
in need of sequences of elements for which <i>more than one</i> sorting criterion is
|
||||
relevant. We do so by defining a <code>multi_index_container</code>
|
||||
instantiation composed of several ordered indices: each index, viewed in isolation,
|
||||
behaves much as an ordered <code>std::set</code> (or <code>std::multiset</code>), whilst
|
||||
@@ -192,6 +123,11 @@ thus can be solved with Boost.MultiIndex as follows:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>member</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
|
||||
<span class=comment>// define a multiply indexed set with indices by id and name</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>employee</span><span class=special>,</span>
|
||||
@@ -217,12 +153,13 @@ thus can be solved with Boost.MultiIndex as follows:
|
||||
|
||||
<p>
|
||||
Instead of a single comparison predicate type, as it happens for STL associative
|
||||
containers, <code>multi_index_container</code> is passed a <i>typelist</i> of index
|
||||
containers, <code>multi_index_container</code> is passed a
|
||||
<a href="../reference/multi_index_container.html#multi_index_container">list</a> of index
|
||||
specifications (<code>indexed_by</code>), each one inducing the corresponding index.
|
||||
Indices are accessed via
|
||||
<a href="reference/multi_index_container.html#index_retrieval"><code>get</code></a><code><N>()</code>
|
||||
<a href="../reference/multi_index_container.html#index_retrieval"><code>get</code></a><code><N>()</code>
|
||||
where <i>N</i> ranges between 0 and the number of comparison
|
||||
predicates minus one. The functionality of index #0 can be accessed directly from an
|
||||
predicates minus one. The functionality of index #0 can be accessed directly from a
|
||||
<code>multi_index_container</code> object without using <code>get<0>()</code>: for instance,
|
||||
<code>es.begin()</code> is equivalent to <code>es.get<0>().begin()</code>.
|
||||
</p>
|
||||
@@ -302,6 +239,11 @@ does precisely this through the combination of sequenced and ordered indices:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</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>sequenced_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
|
||||
<span class=comment>// define a multi_index_container with a list-like index and an ordered index</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
|
||||
@@ -326,7 +268,7 @@ does not show any advantage. The code for inserting the text into the container
|
||||
does not change as sequenced indices provide an interface similar to that of
|
||||
<code>std::list</code> (no explicit access to this index through
|
||||
<code>get<0>()</code> is needed as <code>multi_index_container</code> inherits the
|
||||
functionality of index #0.) But the specification of an additional ordered index
|
||||
functionality of index #0). But the specification of an additional ordered index
|
||||
allows us to implement <code>occurrences</code> and <code>delete_word</code>
|
||||
in a much more efficient manner:
|
||||
</p>
|
||||
@@ -363,7 +305,7 @@ complexity. The programmer can use index #0 for accessing the text as with
|
||||
|
||||
<p>
|
||||
The indices of a <code>multi_index_container</code> instantiation are specified by
|
||||
means of the <a href="reference/indices.html#indexed_by">
|
||||
means of the <a href="../reference/indices.html#indexed_by">
|
||||
<code>indexed_by</code></a> construct. For instance, the instantiation
|
||||
</p>
|
||||
|
||||
@@ -397,7 +339,7 @@ we specifiy two indices, the first of <a href="#seq_indices">sequenced type</a>,
|
||||
the second a non-unique <a href="#ord_indices">ordered index</a>. In general, we
|
||||
can specify an arbitrary number of indices: each of the arguments of
|
||||
<code>indexed_by</code> is called an
|
||||
<a href="reference/indices.html#index_specification"><i>index specifier</i></a>.
|
||||
<a href="../reference/indices.html#index_specification"><i>index specifier</i></a>.
|
||||
Depending on the type of index being specified, the corresponding specifier
|
||||
will need additional information: for instance, the specifiers <code>ordered_unique</code>
|
||||
and <code>ordered_non_unique</code> are provided with a
|
||||
@@ -455,9 +397,9 @@ first parameter of the corresponding index specifier. The following is a revised
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Tags have to be passed inside the <code>tag</code> construct. Any type can be
|
||||
used as a tag for an index, although in general one will choose names that are
|
||||
descriptive of the index they are associated with. The tagging mechanism allows
|
||||
Tags have to be passed inside the <a href="../reference/indices.html#tag"><code>tag</code></a>
|
||||
construct. Any type can be used as a tag for an index, although in general one will choose
|
||||
names that are descriptive of the index they are associated with. The tagging mechanism allows
|
||||
us to write expressions like</p>
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -475,7 +417,7 @@ for instance,
|
||||
<li><code>employee_set::nth_index<1>::type</code> is the type of
|
||||
index #1,</li>
|
||||
<li><code>employee_set::index<name>::type</code> is the type of the index
|
||||
tagged with <code>name</code> (the same index #1 in this case.)</li>
|
||||
tagged with <code>name</code> (the same index #1 in this case).</li>
|
||||
</ul>
|
||||
<code>get()</code>, on the other hand, is overloaded to serve both styles of access:
|
||||
</p>
|
||||
@@ -507,6 +449,43 @@ in the previous example can be rewritten to hold two different tags
|
||||
<span class=special>></span> <span class=identifier>employee_set</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h2><a name="iterator_access">Iterator access</a></h2>
|
||||
|
||||
<p>
|
||||
Each index of a <code>multi_index_container</code> uses its own
|
||||
iterator types, which are different from those of other indices. As is
|
||||
the rule with STL containers, these iterators are defined as nested
|
||||
types of the index:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span>
|
||||
<span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=number>1</span><span class=special>>().</span><span class=identifier>find</span><span class=special>(</span><span class=string>"Judy Smith"</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
This kind of expressions can be rendered more readable by
|
||||
means of user-defined <code>typedef</code>s:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>employee_set_by_name</span><span class=special>;</span>
|
||||
<span class=identifier>employee_set_by_name</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span>
|
||||
<span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=number>1</span><span class=special>>().</span><span class=identifier>find</span><span class=special>(</span><span class=string>"Judy Smith"</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The iterators provided by every index are <i>constant</i>, that is, the elements they point to
|
||||
cannot be mutated directly. This follows the interface of <code>std::set</code> for ordered
|
||||
indices but might come as a surprise for other types such as sequenced indices, which are modeled after
|
||||
<code>std::list</code>, where this limitation does not happen. This seemingly odd behavior
|
||||
is imposed by the way <code>multi_index_container</code>s work; if elements were
|
||||
allowed to be mutated indiscriminately, we could introduce inconsistencies
|
||||
in the ordered indices of the <code>multi_index_container</code> without the container
|
||||
being notified about it. Element modification is properly done by means of
|
||||
<a href="#ord_updating">update operations</a> on any index.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="index_types">Index types</a>
|
||||
</h2>
|
||||
@@ -517,20 +496,25 @@ Currently, Boost.MultiIndex provides the following index types:
|
||||
<li>Ordered indices sort the elements like <code>std::set</code>s do and
|
||||
provide a similar interface. There are <i>unique</i> and <i>non-unique</i>
|
||||
variants: the former do not allow for duplicates, while the latter permit
|
||||
them (like <code>std::multiset</code>.)</li>
|
||||
<li>Hashed indices provide fast access to the elements through hashing
|
||||
tecnhiques, in a similar way as non-standard <code>hash_set</code>s provided
|
||||
by some vendors. Recently, <i>unordered associative containers</i> have been
|
||||
proposed as part of an extension of the C++ standard library known
|
||||
in the standardization commitee as TR1. Hashed indices closely model this
|
||||
proposal.</li>
|
||||
them (like <code>std::multiset</code>).</li>
|
||||
<li>Ranked indices are a variation of ordered indices providing extra capabilities
|
||||
for querying and accessing elements based on their <i>rank</i> (the numerical position
|
||||
they occupy in the index).
|
||||
</li>
|
||||
<li>Sequenced indices are modeled after the semantics and interface of
|
||||
<code>std::list</code>: they arrange the elements as if in a bidirectional
|
||||
list.</li>
|
||||
<li>Hashed indices provide fast access to the elements through hashing
|
||||
techniques, in a similar way as unordered associative containers
|
||||
<code>std::unordered_set</code> (if duplicates are not allowed) and
|
||||
<code>std::unordered_multiset</code> (if they are).</li>
|
||||
<li>Random access indices provide an interface similar to that of
|
||||
sequenced indices, and additionally feature random access iterators
|
||||
and positional access to the elements.</li>
|
||||
</ul>
|
||||
The examples in the <a href="#intro">introduction</a> exercise ordered and sequenced
|
||||
indices, which are the most commonly used; hashed indices are presented in the
|
||||
<a href="advanced_topics.html#hashed_indices">advanced topics</a> section.
|
||||
indices, which are the most commonly used; the other kinds of indices are presented
|
||||
in the <a href="indices.html">index types</a> section of the tutorial.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
@@ -654,13 +638,13 @@ the sorting is performed. In most cases, one of the following two situations ari
|
||||
<ul>
|
||||
<li>The whole element serves as the key, as is the case of the first index
|
||||
in <code>employee_set</code>. The predefined
|
||||
<a href="reference/key_extraction.html#identity"><code>identity</code></a> predicate
|
||||
<a href="key_extraction.html#identity"><code>identity</code></a> predicate
|
||||
can be used here as a key extractor; <code>identity</code> returns as the key the
|
||||
same object passed as argument.</li>
|
||||
<li>The comparison is performed on a particular data member of the element; this
|
||||
closely follows the specification of indices on a column of a table in relational
|
||||
databases. Boost.MultiIndex provides
|
||||
<a href="reference/key_extraction.html#member"><code>member</code></a>, which returns
|
||||
<a href="key_extraction.html#member"><code>member</code></a>, which returns
|
||||
as the key a member of the element specified by a given pointer.</li>
|
||||
</ul>
|
||||
As an example, consider again the definition of <code>employee_set</code>. The
|
||||
@@ -688,78 +672,11 @@ we use <code>member</code> to extract the <code>name</code> part of the
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Another common situation arises when the sorting is performed on the result
|
||||
of a particular member function. This resembles the notion of
|
||||
<i>calculated indices</i> supported by some relational databases.
|
||||
In these cases, the key is not a data member of the element, but rather it is
|
||||
a value returned by a particular member function. Boost.MultiIndex supports this
|
||||
kind of key extraction through
|
||||
<a href="reference/key_extraction.html#const_mem_fun"><code>const_mem_fun</code></a>.
|
||||
Consider the following extension of our example where sorting on the third index
|
||||
is based upon the length of the name field:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>employee</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>id</span><span class=special>;</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>employee</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>id</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&</span> <span class=identifier>name</span><span class=special>):</span><span class=identifier>id</span><span class=special>(</span><span class=identifier>id</span><span class=special>),</span><span class=identifier>name</span><span class=special>(</span><span class=identifier>name</span><span class=special>){}</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special><(</span><span class=keyword>const</span> <span class=identifier>employee</span><span class=special>&</span> <span class=identifier>e</span><span class=special>)</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>id</span><span class=special><</span><span class=identifier>e</span><span class=special>.</span><span class=identifier>id</span><span class=special>;}</span>
|
||||
|
||||
<span class=comment>// returns the length of the name field</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>name_length</span><span class=special>()</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>name</span><span class=special>.</span><span class=identifier>size</span><span class=special>();}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=comment>// sort by employee::operator<</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> <span class=special>>,</span>
|
||||
|
||||
<span class=comment>// sort by less<string> on name</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>></span> <span class=special>>,</span>
|
||||
|
||||
<span class=comment>// sort by less<int> on name_length()</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span>
|
||||
<span class=identifier>const_mem_fun</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name_length</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>employee_set</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p><a href="examples.html#example2">Example 2</a> in the examples section
|
||||
provides a complete program showing how to use <code>const_mem_fun</code>.
|
||||
Almost always you will want to use a <code>const</code> member function,
|
||||
since elements in a <code>multi_index_container</code> are treated as constant, much
|
||||
as elements of an <code>std::set</code>. However, a
|
||||
<a href="reference/key_extraction.html#mem_fun"><code>mem_fun</code></a>
|
||||
counterpart is provided for use with non-constant member functions, whose
|
||||
applicability is discussed on the paragraph on
|
||||
<a href="advanced_topics.html#advanced_key_extractors">advanced features
|
||||
of Boost.MultiIndex key extractors</a> in the advanced topics section.
|
||||
<p>
|
||||
|
||||
<p>
|
||||
More complex scenarios may require the use of
|
||||
<i>composite keys</i> combining the results of several key extractors.
|
||||
Composite keys are supported by Boost.MultiIndex through the
|
||||
<a href="advanced_topics.html#composite_keys"><code>composite_key</code></a>
|
||||
construct.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>identity</code>, <code>member</code> and <code>const_mem_fun</code>
|
||||
(occasionally combined with <code>composite_key</code>) serve
|
||||
most common situations in the design of a <code>multi_index_container</code>. However, the
|
||||
user is free to provide her own key extractors in more exotic situations, as long as
|
||||
these conform to the <a href="reference/key_extraction.html#key_extractors"><code>Key
|
||||
Extractor</code></a> concept. For instance,
|
||||
<a href="examples.html#example6">example 6</a> implements several key
|
||||
extraction techniques called for when elements and/or keys are accessed via
|
||||
pointers.
|
||||
Apart from <code>identity</code> and <code>member</code>, Boost.MultiIndex provides
|
||||
several other predefined key extractors and powerful ways to combine them.
|
||||
Key extractors can also be defined by the user.
|
||||
Consult the <a href="key_extraction.html">key extraction section</a> of
|
||||
the tutorial for a more detailed exposition of this topic.
|
||||
</p>
|
||||
|
||||
<h4><a name="comparison_predicates">Comparison predicates</a></h4>
|
||||
@@ -848,8 +765,8 @@ comparison predicate
|
||||
Here we are not only passing IDs instead of <code>employee</code> objects:
|
||||
an alternative comparison predicate is passed as well. In general, lookup operations
|
||||
of ordered indices are overloaded to accept
|
||||
<a href="reference/ord_indices.html#set_operations"><i>compatible sorting
|
||||
criteria</i></a>. The somewhat cumbersone definition of compatibility in this context
|
||||
<a href="../reference/ord_indices.html#set_operations"><i>compatible sorting
|
||||
criteria</i></a>. The somewhat cumbersome definition of compatibility in this context
|
||||
is given in the reference, but roughly speaking we say that a comparison predicate
|
||||
<code>C1</code> is compatible with <code>C2</code> if any sequence sorted by
|
||||
<code>C2</code> is also sorted with respect to <code>C1</code>.
|
||||
@@ -884,7 +801,7 @@ The following shows a more interesting use of compatible predicates:
|
||||
Range searching, i.e. the lookup of all elements in a given interval, is a very
|
||||
frequent operation for which standard <code>lower_bound</code> and
|
||||
<code>upper_bound</code> can be resorted to, though in a cumbersome manner.
|
||||
For instance, the following code retrieves the elements of an
|
||||
For instance, the following code retrieves the elements of a
|
||||
<code>multi_index_container<double></code> in the interval [100,200]:
|
||||
</p>
|
||||
|
||||
@@ -923,9 +840,9 @@ and error prone task.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <a href="reference/ord_indices.html#range_operations"><code>range</code></a>
|
||||
The <a href="../reference/ord_indices.html#range_operations"><code>range</code></a>
|
||||
member function, often in combination with
|
||||
<a href="../../../libs/lambda/index.html">Boost.Lambda</a> expressions, can
|
||||
<a href="../../../../libs/lambda/index.html">Boost.Lambda</a> expressions, can
|
||||
greatly help alleviate this situation:
|
||||
</p>
|
||||
|
||||
@@ -961,7 +878,7 @@ One or both bounds can be omitted with the special <code>unbounded</code> marker
|
||||
<h4><a name="ord_updating">Updating</a></h4>
|
||||
|
||||
<p>
|
||||
The <a href="reference/ord_indices.html#replace"><code>replace</code></a> member function
|
||||
The <a href="../reference/ord_indices.html#replace"><code>replace</code></a> member function
|
||||
performs in-place replacement of a given element as the following example shows:
|
||||
</p>
|
||||
|
||||
@@ -997,7 +914,7 @@ the updating (when retrieving it and inside <code>replace</code>). If elements
|
||||
are expensive to copy, this may be quite a computational cost for the modification
|
||||
of just a tiny part of the object. To cope with this situation, Boost.MultiIndex
|
||||
provides an alternative updating mechanism called
|
||||
<a href="reference/ord_indices.html#modify"><code>modify</code></a>:
|
||||
<a href="../reference/ord_indices.html#modify"><code>modify</code></a>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -1034,18 +951,69 @@ original value is kept and the method returns without altering the container, bu
|
||||
leaves no trace of the previous value of the element. Integrity constraints
|
||||
thus lead to the following policy: when a collision happens in the
|
||||
process of calling <code>modify</code>, the element is erased and the method returns
|
||||
<code>false</code>. This difference in behavior between <code>replace</code> and
|
||||
<code>modify</code> has to be considered by the programmer on a case-by-case basis.
|
||||
<code>false</code>. There is a further version of <code>modify</code> which
|
||||
accepts a <i>rollback</i> functor to undo the changes in case of collision:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>change_id</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>change_id</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>new_id</span><span class=special>):</span><span class=identifier>new_id</span><span class=special>(</span><span class=identifier>new_id</span><span class=special>){}</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>employee</span><span class=special>&</span> <span class=identifier>e</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>e</span><span class=special>.</span><span class=identifier>id</span><span class=special>=</span><span class=identifier>new_id</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>private</span><span class=special>:</span>
|
||||
<span class=keyword>int</span> <span class=identifier>new_id</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
<span class=special>...</span>
|
||||
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=...</span>
|
||||
|
||||
<span class=keyword>int</span> <span class=identifier>old_id</span><span class=special>=</span><span class=identifier>it</span><span class=special>-></span><span class=identifier>id</span><span class=special>;</span> <span class=comment>// keep the original id
|
||||
|
||||
// try to modify the id, restore it in case of collisions</span>
|
||||
<span class=identifier>es</span><span class=special>.</span><span class=identifier>modify</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>change_id</span><span class=special>(</span><span class=number>321</span><span class=special>),</span><span class=identifier>change_id</span><span class=special>(</span><span class=identifier>old_id</span><span class=special>));</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>In the example, <code>change_id(old_id)</code> is invoked to restore the original
|
||||
conditions when the modification results in collisions with some other element.
|
||||
The differences in behavior between <code>replace</code>, <code>modify</code> and
|
||||
<code>modify</code> with rollback have to be considered by the programmer on a
|
||||
case-by-case basis to determine the best updating mechanism.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<caption><b>Behavior of the different updating mechanisms.</b></caption>
|
||||
<tr>
|
||||
<th align="center">updating function</th>
|
||||
<th>If there is a collision...</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><code>replace(it,x)</code></td>
|
||||
<td>replacement does not take place.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td align="center"><code>modify(it,mod)</code></td>
|
||||
<td>the element is erased.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><code>modify(it,mod,back)</code></td>
|
||||
<td><code>back</code> is used to restore the original conditions.
|
||||
(If <code>back</code> throws, the element is erased.)
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
A key-based version of <code>modify</code>, named
|
||||
<a href="reference/ord_indices.html#modify_key"><code>modify_key</code></a>, is
|
||||
provided as well. In this case, the modifying functor is passed a reference to
|
||||
the <code>key_value</code> part of the element instead of the whole object. Note
|
||||
that <code>modify_key</code> cannot be used for key extractors which return calculated
|
||||
values instead of references to data members of the elements, such
|
||||
as <code>const_mem_fun</code>.
|
||||
Key-based versions of <code>modify</code>, named
|
||||
<a href="../reference/ord_indices.html#modify_key"><code>modify_key</code></a>, are
|
||||
provided as well. In this case, the modifying functors are passed a reference to
|
||||
the <code>key_type</code> part of the element instead of the whole object.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -1071,10 +1039,10 @@ as <code>const_mem_fun</code>.
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Just as <code>modify</code> does, <code>modify_key</code> erases the element if
|
||||
the modification results in collisions in some index. <code>modify</code> and
|
||||
Like <code>modify</code>, there are versions of <code>modify_key</code> with and
|
||||
without rollback. <code>modify</code> and
|
||||
<code>modify_key</code> are particularly well suited to use in conjunction to
|
||||
<a href="../../../libs/lambda/index.html">Boost.Lambda</a>
|
||||
<a href="../../../../libs/lambda/index.html">Boost.Lambda</a>
|
||||
for defining the modifying functors:
|
||||
</p>
|
||||
|
||||
@@ -1088,6 +1056,13 @@ for defining the modifying functors:
|
||||
<span class=identifier>name_index</span><span class=special>.</span><span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>_1</span><span class=special>=</span><span class=string>"Anna Smith"</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>modify_key</code> requires that the key extractor be of
|
||||
a special type called
|
||||
<a href="key_extraction.html#read_write_key_extractors">read/write</a>:
|
||||
this is usually, but not always, the case.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
<a name="seq_indices">Sequenced indices</a>
|
||||
</h3>
|
||||
@@ -1099,27 +1074,23 @@ same way as <code>std::list</code> permits. The interface of sequenced indices
|
||||
is thus designed upon that of <code>std::list</code>; nearly every operation
|
||||
provided in the standard container is replicated here, occasionally with changes
|
||||
in the syntax and/or semantics to cope with the constraints imposed by
|
||||
Boost.MultiIndex. In particular, there is an important limitation of sequenced
|
||||
indices with respect to <code>std::list</code>s, namely that elements of an
|
||||
<code>multi_index_container</code> are not mutable through an iterator:
|
||||
Boost.MultiIndex. An important difference, commented <a href="#iterator_access">above</a>,
|
||||
is the fact that the values pointed to by sequenced index iterators are treated
|
||||
as <i>constant</i>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>s</span><span class=special>;</span> <span class=comment>// list-like container</span>
|
||||
<span class=special>></span> <span class=identifier>s</span><span class=special>;</span> <span class=comment>// list-like container</span>
|
||||
|
||||
<span class=identifier>s</span><span class=special>.</span><span class=identifier>push_front</span><span class=special>(</span><span class=number>0</span><span class=special>);</span>
|
||||
<span class=special>*(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>())==</span><span class=number>1</span><span class=special>;</span> <span class=comment>// ERROR: the element cannot be changed</span>
|
||||
<span class=special>*(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>())=</span><span class=number>1</span><span class=special>;</span> <span class=comment>// ERROR: the element cannot be changed</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
That is, iterators of a sequenced index (of all types of indices, actually)
|
||||
point to constant elements. This limitation might come as a surprise, but
|
||||
it is imposed by the way <code>multi_index_container</code>s work; if elements were
|
||||
allowed to be changed in this manner, we could introduce inconsistencies
|
||||
in other ordered indices of the <code>multi_index_container</code>. Element modification
|
||||
As with any other type of index, element modification
|
||||
can nevertheless be done by means of
|
||||
<a href="#seq_updating">update operations</a>.
|
||||
</p>
|
||||
@@ -1178,15 +1149,15 @@ do not always coincide with those of the standard container. Differences
|
||||
result mainly from the fact that insertions into a sequenced index are not
|
||||
guaranteed to succeed, due to the possible banning by other indices
|
||||
of the <code>multi_index_container</code>. Consult the
|
||||
<a href="reference/seq_indices.html">reference</a> for further details.
|
||||
<a href="../reference/seq_indices.html">reference</a> for further details.
|
||||
</p>
|
||||
|
||||
<h4><a name="seq_updating">Updating</a></h4>
|
||||
|
||||
<p>
|
||||
Like ordered indices, sequenced indices provide
|
||||
<a href="reference/seq_indices.html#replace"><code>replace</code></a> and
|
||||
<a href="reference/seq_indices.html#modify"><code>modify</code></a>
|
||||
<a href="../reference/seq_indices.html#replace"><code>replace</code></a> and
|
||||
<a href="../reference/seq_indices.html#modify"><code>modify</code></a>
|
||||
operations, with identical functionality. There is however no analogous
|
||||
<code>modify_key</code>, since sequenced indices are not key-based.
|
||||
</p>
|
||||
@@ -1195,7 +1166,7 @@ operations, with identical functionality. There is however no analogous
|
||||
|
||||
<p>
|
||||
Given indices <code>i1</code> and <code>i2</code> on the same <code>multi_index_container</code>,
|
||||
<a href="reference/multi_index_container.html#projection"><code>project</code></a> can be used to
|
||||
<a href="../reference/multi_index_container.html#projection"><code>project</code></a> can be used to
|
||||
retrieve an <code>i2</code>-iterator from an <code>i1</code>-iterator, both of them
|
||||
pointing to the same element of the container. This functionality allows the programmer to
|
||||
move between different indices of the same <code>multi_index_container</code> when performing
|
||||
@@ -1228,7 +1199,7 @@ A slightly more interesting example:
|
||||
|
||||
<span class=comment>// prepend "older" to all occurrences of "sister"</span>
|
||||
|
||||
<span class=identifier>text_container</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>it1</span><span class=special>=</span>
|
||||
<span class=identifier>text_container</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it1</span><span class=special>=</span>
|
||||
<span class=identifier>sorted_index</span><span class=special>.</span><span class=identifier>lower_bound</span><span class=special>(</span><span class=string>"sister"</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>while</span><span class=special>(</span><span class=identifier>it1</span><span class=special>!=</span><span class=identifier>sorted_index</span><span class=special>.</span><span class=identifier>end</span><span class=special>()&&*</span><span class=identifier>it1</span><span class=special>==</span><span class=string>"sister"</span><span class=special>){</span>
|
||||
@@ -1257,33 +1228,33 @@ is preserved in the face of insertions, even for replace and modify operations.
|
||||
Appropriate instantiations of <code>multi_index_container</code> can in fact simulate
|
||||
<code>std::set</code>, <code>std::multiset</code> and (with more limitations)
|
||||
<code>std::list</code>, as shown in the
|
||||
<a href="advanced_topics.html#simulate_std_containers">advanced topics</a>
|
||||
section. These simulations are as nearly as efficient as the original STL
|
||||
containers; consult the <a href="reference/index.html">reference</a> for further
|
||||
<a href="techniques.html#emulate_std_containers">techniques</a>
|
||||
section. These simulations are nearly as efficient as the original STL
|
||||
containers; consult the <a href="../reference/index.html">reference</a> for further
|
||||
information on complexity guarantees and the
|
||||
<a href="performance.html">performance section</a> for practical measurements of
|
||||
<a href="../performance.html">performance section</a> for practical measurements of
|
||||
efficiency.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="index.html"><img src="prev.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
<div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="tutorial" border="0"><br>
|
||||
Boost.MultiIndex Tutorial
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="advanced_topics.html"><img src="next.gif" alt="advanced topics" border="0"><br>
|
||||
Advanced topics
|
||||
<div class="next_link"><a href="indices.html"><img src="../next.gif" alt="index types" border="0"><br>
|
||||
Index types
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised March 31st 2005</p>
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
License, 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>
|
||||
@@ -0,0 +1,353 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Tutorial - Container creation</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="key_extraction.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="debug.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Container creation</h1>
|
||||
|
||||
<div class="prev_link"><a href="key_extraction.html"><img src="../prev.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="debug.html"><img src="../next.gif" alt="debugging support" border="0"><br>
|
||||
Debugging support
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#value_semantics">Value semantics</a></li>
|
||||
<li><a href="#ctor_args_list">Use of <code>ctor_args_list</code></a></li>
|
||||
<li><a href="#special_allocator">Special allocator support</a></li>
|
||||
<li><a href="#serialization">Serialization</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="value_semantics">Value semantics</a></h2>
|
||||
|
||||
<p>
|
||||
<code>multi_index_container</code>s have the usual value semantics associated
|
||||
to copy construction and assignment, i.e. copies of the elements from the source
|
||||
container are created and inserted into the destination container.
|
||||
More interestingly, copying also recreates the original order in which
|
||||
elements are arranged for <i>every index</i> of the container.
|
||||
This implies that equality of all indices is preserved under copying
|
||||
or assignment, for those index types where equality is defined. This behavior
|
||||
can be regarded as a natural extension to the general rule on copy semantics
|
||||
stating that if <code>y</code> is a copy of <code>x</code>, then
|
||||
<code>y==x</code>.
|
||||
</p>
|
||||
|
||||
<h2><a name="ctor_args_list">Use of <code>ctor_args_list</code></a></h2>
|
||||
|
||||
<p>
|
||||
Although in most cases <code>multi_index_container</code>s will be default constructed
|
||||
(or copied from a preexisting <code>multi_index_container</code>), sometimes it is
|
||||
necessary to specify particular values for the internal objects used (key extractors,
|
||||
comparison predicates, allocator), for instance if some of these objects do not have
|
||||
a default constructor. The same situation can arise with standard STL containers,
|
||||
which allow for the optional specification of such objects:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// example of non-default constructed std::set</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>IntegralType</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>modulo_less</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>modulo_less</span><span class=special>(</span><span class=identifier>IntegralType</span> <span class=identifier>m</span><span class=special>):</span><span class=identifier>modulo</span><span class=special>(</span><span class=identifier>m</span><span class=special>){}</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>IntegralType</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>IntegralType</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>(</span><span class=identifier>x</span><span class=special>%</span><span class=identifier>modulo</span><span class=special>)<(</span><span class=identifier>y</span><span class=special>%</span><span class=identifier>modulo</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>private</span><span class=special>:</span>
|
||||
<span class=identifier>IntegralType</span> <span class=identifier>modulo</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>,</span><span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>></span> <span class=identifier>modulo_set</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>modulo_set</span> <span class=identifier>m</span><span class=special>(</span><span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>(</span><span class=number>10</span><span class=special>));</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>multi_index_container</code> does also provide this functionality, though in a
|
||||
considerably more complex fashion, due to the fact that the constructor
|
||||
of a <code>multi_index_container</code> has to accept values for all the internal
|
||||
objects of its indices. The full form of <code>multi_index_container</code> constructor
|
||||
is
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
|
||||
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The specification of the allocator object poses no particular problems;
|
||||
as for the <code>ctor_args_list</code>, this object is designed so as to hold
|
||||
the necessary construction values for every index in the <code>multi_index_container</code>.
|
||||
From the point of view of the user, <code>ctor_args_list</code> is equivalent
|
||||
to the type
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><</span><span class=identifier>C<sub>0</sub></span><span class=special>,...,</span><span class=identifier>C<sub>I-1</sub></span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
where <code>I</code> is the number of indices, and <code>C<sub>i</sub></code> is
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>nth_index</span><span class=special><</span><span class=identifier>i</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
that is, the nested type <code>ctor_args</code> of the <code>i</code>-th index. Each
|
||||
<code>ctor_args</code> type is in turn a tuple holding values for constructor
|
||||
arguments of the associated index: so, ordered indices demand a key extractor object
|
||||
and a comparison predicate, hashed indices take an initial number of buckets,
|
||||
a key extractor, a hash function and an equality predicate; while sequenced
|
||||
and random access indices do not need any construction argument. For instance,
|
||||
given the definition
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>hashed_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>,</span> <span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>sequenced</span><span class=special><>,</span>
|
||||
<span class=identifier>random_access</span><span class=special><></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>modulo_indexed_set</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
the corresponding <code>ctor_args_list</code> type is equivalent to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><</span>
|
||||
<span class=comment>// ctr_args of index #0</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span><span class=special>,</span> <span class=comment>// initial number of buckets; 0 if unspecified</span>
|
||||
<span class=identifier>identity</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
|
||||
<span class=comment>// ctr_args of index #1</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><</span>
|
||||
<span class=identifier>identity</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>,</span>
|
||||
<span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
|
||||
<span class=comment>// sequenced indices do not have any construction argument</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><>,</span>
|
||||
|
||||
<span class=comment>// neither do random access indices</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Such a <code>modulo_indexed_set</code> cannot be default constructed, because
|
||||
<code>modulo_less</code> does not provide a default constructor. The following shows
|
||||
how the construction can be done:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>ctor_args_list</span> <span class=identifier>args_list</span><span class=special>=</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>make_tuple</span><span class=special>(</span>
|
||||
<span class=comment>// ctor_args for index #0 is default constructible</span>
|
||||
<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>0</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>(),</span>
|
||||
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>make_tuple</span><span class=special>(</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>(),</span><span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>(</span><span class=number>10</span><span class=special>)),</span>
|
||||
|
||||
<span class=comment>// these are also default constructible (actually, empty tuples)</span>
|
||||
<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>2</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>(),</span>
|
||||
<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>3</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>()</span>
|
||||
<span class=special>);</span>
|
||||
|
||||
<span class=identifier>modulo_indexed_set</span> <span class=identifier>m</span><span class=special>(</span><span class=identifier>args_list</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
A program is provided in the <a href="../examples.html#example3">examples section</a> that
|
||||
puts in practise these concepts.
|
||||
</p>
|
||||
|
||||
<h2><a name="special_allocator">Special allocator support</a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex allows for a slightly more general class of allocators
|
||||
than strictly required by the C++ standard, as explained in detail in the
|
||||
<a href="../reference/multi_index_container.html#instantiation_types">reference</a>.
|
||||
An important type of non-standard allocators supported are those provided by the
|
||||
<a href="../../../interprocess/index.html">Boost Interprocess Library</a>;
|
||||
this opens up the possibility of placing <code>multi_index_container</code>s
|
||||
and their iterators in shared memory.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>allocators</span><span class=special>/</span><span class=identifier>allocator</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>managed_shared_memory</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>bip</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>interprocess</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// a shared memory compatible allocator of ints</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>bip</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span><span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span><span class=special>::</span><span class=identifier>segment_manager</span>
|
||||
<span class=special>></span> <span class=identifier>shared_int_allocator</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// define a shared memory compatible multi_index_container
|
||||
// using shared_int_allocator</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>sequenced</span><span class=special><>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>shared_int_allocator</span>
|
||||
<span class=special>></span> <span class=identifier>unique_int_list</span><span class=special>;</span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=comment>// create a managed memory segment</span>
|
||||
<span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span> <span class=identifier>seg</span><span class=special>(</span>
|
||||
<span class=identifier>bip</span><span class=special>::</span><span class=identifier>create_only</span><span class=special>,</span><span class=string>"SharedMemoryID"</span><span class=special>,</span><span class=number>65536</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// construct a unique_int_list into the segment</span>
|
||||
<span class=identifier>unique_int_list</span><span class=special>*</span> <span class=identifier>puil</span><span class=special>=</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>construct</span><span class=special><</span><span class=identifier>unique_int_list</span><span class=special>></span>
|
||||
<span class=special>(</span><span class=string>"UniqueIntListID"</span><span class=special>)</span> <span class=comment>// object identifier within the segment
|
||||
// Construction args: first a ctor arg list, then a
|
||||
// shared memory allocator obtained from the segment object.</span>
|
||||
<span class=special>(</span><span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
|
||||
<span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>allocator_type</span><span class=special>(</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>get_segment_manager</span><span class=special>()));</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The examples section includes a <a href="../examples.html#example12">program</a>
|
||||
that further explores this capability.
|
||||
</p>
|
||||
|
||||
<h2><a name="serialization">Serialization</a></h2>
|
||||
|
||||
<p>
|
||||
<code>multi_index_container</code>s can be archived and retrieved by means of the
|
||||
<a href="../../../serialization/index.html">Boost Serialization Library</a>. Both regular
|
||||
and XML archives are supported. The usage is straightforward and does not
|
||||
differ from that of any other serializable type. For instance:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>archive</span><span class=special>/</span><span class=identifier>text_oarchive</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>archive</span><span class=special>/</span><span class=identifier>text_iarchive</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>fstream</span><span class=special>></span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>save</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>es</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>ofstream</span> <span class=identifier>ofs</span><span class=special>(</span><span class=string>"data"</span><span class=special>);</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>archive</span><span class=special>::</span><span class=identifier>text_oarchive</span> <span class=identifier>oa</span><span class=special>(</span><span class=identifier>ofs</span><span class=special>);</span>
|
||||
<span class=identifier>oa</span><span class=special><<</span><span class=identifier>es</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>load</span><span class=special>(</span><span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>es</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>ifstream</span> <span class=identifier>ifs</span><span class=special>(</span><span class=string>"data"</span><span class=special>);</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>archive</span><span class=special>::</span><span class=identifier>text_iarchive</span> <span class=identifier>ia</span><span class=special>(</span><span class=identifier>ifs</span><span class=special>);</span>
|
||||
<span class=identifier>ia</span><span class=special>>></span><span class=identifier>es</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
|
||||
<span class=special>...</span> <span class=comment>// fill it with data</span>
|
||||
<span class=identifier>save</span><span class=special>(</span><span class=identifier>es</span><span class=special>);</span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=identifier>employee_set</span> <span class=identifier>restored_es</span><span class=special>;</span>
|
||||
<span class=identifier>load</span><span class=special>(</span><span class=identifier>restored_es</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Serialization capabilities are automatically provided by just linking with
|
||||
the appropriate Boost.Serialization library module: it is not necessary
|
||||
to explicitly include any header from Boost.Serialization,
|
||||
apart from those declaring the type of archive used in the process. If not used,
|
||||
however, serialization support can be disabled by globally defining the macro
|
||||
<code>BOOST_MULTI_INDEX_DISABLE_SERIALIZATION</code>. Disabling serialization
|
||||
for Boost.MultiIndex can yield a small improvement in build times, and may
|
||||
be necessary in those defective compilers that fail to correctly process
|
||||
Boost.Serialization headers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In accordance with Boost.MultiIndex
|
||||
<a href="#value_semantics">value semantics</a>, retrieving an
|
||||
archived <code>multi_index_container</code> restores not only
|
||||
the elements, but also the order they were arranged into for
|
||||
every index of the container. There is an exception to this rule,
|
||||
though: for <a href="indices.html#hashed_indices">hashed
|
||||
indices</a>, no guarantee is made about the order in which elements will
|
||||
be iterated in the restored container; in general, it is unwise to rely on
|
||||
the ordering of elements of a hashed index, since it can change in arbitrary
|
||||
ways during insertion or rehashing --this is precisely the reason why
|
||||
hashed indices and TR1 unordered associative containers do not define
|
||||
an equality operator.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Iterators to indices of a <code>multi_index_container</code> can also be
|
||||
serialized. Serialization of iterators must be done only after serializing
|
||||
their corresponding container.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="../examples.html#example9">Example 9</a> in the examples section shows
|
||||
the serialization capabilities of Boost.MultiIndex.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="key_extraction.html"><img src="../prev.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="debug.html"><img src="../next.gif" alt="debugging support" border="0"><br>
|
||||
Debugging support
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised June 27th 2026</p>
|
||||
|
||||
<p>© Copyright 2003-2026 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,274 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Tutorial -Debugging support</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="creation.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="techniques.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Debugging support</h1>
|
||||
|
||||
<div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br>
|
||||
Container creation
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br>
|
||||
Techniques
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#debugging_support">Debugging support</a></li>
|
||||
<li><a href="#safe_mode">Safe mode</a>
|
||||
<ul>
|
||||
<li><a href="#serialization_and_safe_mode">Serialization and safe mode</a></li>
|
||||
<li><a href="#shared_memory_and_safe_mode">Containers placed in shared memory</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#invariant_check">Invariant-checking mode</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="debugging_support">Debugging support</a></h2>
|
||||
|
||||
<p>
|
||||
The concept of <i>Design by Contract</i>, originally developed as part
|
||||
of Bertrand Meyer's <a href="http://www.eiffel.com">Eiffel</a> language,
|
||||
revolves around the formulation of a <i>contract</i> between the user
|
||||
of a library and the implementor, by which the first is required to
|
||||
respect some <i>preconditions</i> on the values passed when invoking
|
||||
methods of the library, and the implementor guarantees in return
|
||||
that certain constraints on the results are met (<i>postconditions</i>),
|
||||
as well as the honoring of specified internal consistency rules, called
|
||||
<i>invariants</i>. Eiffel natively supports the three parts of the
|
||||
contract just described by means of constructs <code>require</code>,
|
||||
<code>ensure</code> and <code>invariant</code>, respectively.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
C++ does not enjoy direct support for Design by Contract techniques: these
|
||||
are customarily implemented as assertion code, often turned off in
|
||||
release mode for performance reasons. Following this approach,
|
||||
Boost.MultiIndex provides two distinct debugging modes:
|
||||
<ul>
|
||||
<li><i>Safe mode</i> checks preconditions on the invocations to the
|
||||
facilities of the library,</li>
|
||||
<li><i>invariant-checking mode</i> performs post-execution checks aimed
|
||||
at ensuring that the internal consistency of the library is preserved.</li>
|
||||
</ul>
|
||||
These two modes are independent of each other and can be set on or off
|
||||
individually. It is important to note that errors detected by safe mode are
|
||||
due in principle to faulty code in the user's program, while
|
||||
invariant-checking mode detects potential <i>internal</i> bugs in the
|
||||
implementation of Boost.MultiIndex.
|
||||
</p>
|
||||
|
||||
<h2><a name="safe_mode">Safe mode</a></h2>
|
||||
|
||||
<p>
|
||||
The idea of adding precondition checking facilities to STL as a debugging aid
|
||||
was first introduced by Cay S. Horstmann in his
|
||||
<a href="http://www.horstmann.com/safestl.html">Safe STL</a> library and later
|
||||
adopted by <a href="http://www.stlport.com/doc/debug_mode.html">STLport Debug
|
||||
Mode</a>. Similarly, Boost.MultiIndex features the so-called <i>safe mode</i>
|
||||
in which all sorts of preconditions are checked when dealing with iterators
|
||||
and functions of the library.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex safe mode is set by globally defining the macro
|
||||
<code>BOOST_MULTI_INDEX_ENABLE_SAFE_MODE</code>. Error conditions
|
||||
are checked via the macro <code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, which
|
||||
by default resolves to a call to <a href="../../../../libs/assert">
|
||||
<code>BOOST_ASSERT</code></a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the user decides to define her own version of
|
||||
<code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, it has to take the form
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</span><span class=special>(</span><span class=identifier>expr</span><span class=special>,</span><span class=identifier>error_code</span><span class=special>)</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
where <code>expr</code> is the condition checked and <code>error_code</code>
|
||||
is one value of the <code>safe_mode::error_code</code> enumeration:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>safe_mode</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>enum</span> <span class=identifier>error_code</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>invalid_iterator</span><span class=special>,</span> <span class=comment>// vg. default cted or pointing to erased element</span>
|
||||
<span class=identifier>not_dereferenceable_iterator</span><span class=special>,</span> <span class=comment>// iterator is not dereferenceable</span>
|
||||
<span class=identifier>not_incrementable_iterator</span><span class=special>,</span> <span class=comment>// iterator points to end of sequence</span>
|
||||
<span class=identifier>not_decrementable_iterator</span><span class=special>,</span> <span class=comment>// iterator points to beginning of sequence</span>
|
||||
<span class=identifier>not_owner</span><span class=special>,</span> <span class=comment>// iterator does not belong to the container</span>
|
||||
<span class=identifier>not_same_owner</span><span class=special>,</span> <span class=comment>// iterators belong to different containers</span>
|
||||
<span class=identifier>invalid_range</span><span class=special>,</span> <span class=comment>// last not reachable from first</span>
|
||||
<span class=identifier>inside_range</span><span class=special>,</span> <span class=comment>// iterator lies within a range (and it mustn't)</span>
|
||||
<span class=identifier>out_of_bounds</span><span class=special>,</span> <span class=comment>// move attempted beyond container limits</span>
|
||||
<span class=identifier>same_container</span><span class=special>,</span> <span class=comment>// containers ought to be different</span>
|
||||
<span class=identifier>unequal_allocators</span> <span class=comment>// allocators ought to be equal</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace multi_index::safe_mode</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
For instance, the following replacement of
|
||||
<code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code> throws an exception instead of
|
||||
asserting:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>/</span><span class=identifier>safe_mode_errors</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>safe_mode_exception</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>safe_mode_exception</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>safe_mode</span><span class=special>::</span><span class=identifier>error_code</span> <span class=identifier>error_code</span><span class=special>):</span>
|
||||
<span class=identifier>error_code</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>)</span>
|
||||
<span class=special>{}</span>
|
||||
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>safe_mode</span><span class=special>::</span><span class=identifier>error_code</span> <span class=identifier>error_code</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</span><span class=special>(</span><span class=identifier>expr</span><span class=special>,</span><span class=identifier>error_code</span><span class=special>)</span> <span class=special>\</span>
|
||||
<span class=keyword>if</span><span class=special>(!(</span><span class=identifier>expr</span><span class=special>)){</span><span class=keyword>throw</span> <span class=identifier>safe_mode_exception</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>);}</span>
|
||||
|
||||
<span class=comment>// This has to go before the inclusion of any header from Boost.MultiIndex,
|
||||
// except possibly safe_error_codes.hpp.</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Other possibilities, like outputting to a log or firing some kind of alert, are
|
||||
also implementable.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Warning:</b> Safe mode adds a very important overhead to the program
|
||||
both in terms of space and time used, so in general it should not be set for
|
||||
<code>NDEBUG</code> builds. Also, this mode is intended solely as a debugging aid,
|
||||
and programs must not rely on it as part of their normal execution flow: in
|
||||
particular, no guarantee is made that all possible precondition errors are diagnosed,
|
||||
or that the checks remain stable across different versions of the library.
|
||||
</p>
|
||||
|
||||
<h3><a name="serialization_and_safe_mode">Serialization and safe mode</a></h3>
|
||||
|
||||
<p>
|
||||
Iterators restored from an archive are not subject to safe mode checks. This is
|
||||
so because it is not possible to automatically know the associated
|
||||
<code>multi_index_container</code> of an iterator from the serialization
|
||||
information alone. However, if desired, a restored iterator can be converted to a
|
||||
checked value by using the following workaround:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
|
||||
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// restore es and it from an archive ar</span>
|
||||
<span class=identifier>ar</span><span class=special>>></span><span class=identifier>es</span><span class=special>;</span>
|
||||
<span class=identifier>ar</span><span class=special>>></span><span class=identifier>it</span><span class=special>;</span> <span class=comment>// it won't benefit from safe mode checks
|
||||
|
||||
// Turn it into a checked value by providing Boost.MultiIndex
|
||||
// with info about the associated container.
|
||||
// This statement has virtually zero cost if safe mode is turned off.</span>
|
||||
<span class=identifier>it</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=number>1</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="shared_memory_and_safe_mode">Containers placed in shared memory</a></h3>
|
||||
|
||||
<p>
|
||||
In general, safe mode <b>can't be used</b> when placing <code>multi_index_container</code>s
|
||||
in shared memory for interprocess communication
|
||||
(as in <a href="../examples.html#example12">this example</a>).
|
||||
There are some fundamental reasons for this limitation:
|
||||
<ul>
|
||||
<li>
|
||||
Operations from one process may invalidate or change ownership for iterators
|
||||
living in non-shared memory within another process: safe-mode machinery can't
|
||||
access those for bookkeeping.
|
||||
</li>
|
||||
<li>
|
||||
Safe mode uses internal mutexes not suitable for interprocess
|
||||
synchronization or persistence to a memory-mapped file.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="invariant_check">Invariant-checking mode</a></h2>
|
||||
|
||||
<p>
|
||||
The so called <i>invariant-checking mode</i> of Boost.MultiIndex can be
|
||||
set by globally defining the macro
|
||||
<code>BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING</code>.
|
||||
When this mode is in effect, all public functions of Boost.MultiIndex
|
||||
will perform post-execution tests aimed at ensuring that the basic
|
||||
internal invariants of the data structures managed are preserved.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If an invariant test fails, Boost.MultiIndex will indicate the failure
|
||||
by means of the unary macro <code>BOOST_MULTI_INDEX_INVARIANT_ASSERT</code>.
|
||||
Unless the user provides a definition for this macro, it defaults to
|
||||
<a href="../../../../libs/assert">
|
||||
<code>BOOST_ASSERT</code></a>. Any assertion of this kind should
|
||||
be regarded in principle as a bug in the library. Please report such
|
||||
problems, along with as much contextual information as possible, to the
|
||||
maintainer of the library.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is recommended that users of Boost.MultiIndex always set the
|
||||
invariant-checking mode in debug builds.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br>
|
||||
Container creation
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br>
|
||||
Techniques
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised June 27th 2026</p>
|
||||
|
||||
<p>© Copyright 2003-2026 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,139 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Tutorial</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="../index.html">
|
||||
<link rel="up" href="../index.html">
|
||||
<link rel="next" href="basics.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Tutorial</h1>
|
||||
|
||||
<div class="prev_link"><a href="../index.html"><img src="../prev.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="up_link"><a href="../index.html"><img src="../up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="basics.html"><img src="../next.gif" alt="basics" border="0"><br>
|
||||
Basics
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#rationale">Rationale</a></li>
|
||||
<li><a href="#namespace">Namespace</a></li>
|
||||
<li><a href="basics.html">Basics</a></li>
|
||||
<li><a href="indices.html">Index types</a></li>
|
||||
<li><a href="key_extraction.html">Key extraction</a></li>
|
||||
<li><a href="creation.html">Container creation</a></li>
|
||||
<li><a href="debug.html">Debugging support</a></li>
|
||||
<li><a href="techniques.html">Techniques</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="rationale">Rationale</a></h2>
|
||||
|
||||
<p>
|
||||
STL containers are designed around the concept that each container controls its
|
||||
own collection of elements, giving access to them in a manner specified by the
|
||||
container's type: so, an <code>std::set</code> maintains the elements ordered
|
||||
by a specified sorting criterion, <code>std::list</code> allows for free
|
||||
positioning of elements along a linear sequence, and so on.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sometimes, the necessity arises of having different access interfaces
|
||||
to the same underlying collection: for instance, some data might need to be
|
||||
sorted according to more than one comparison predicate, or a bidirectional list
|
||||
might benefit from a supplemental logarithmic lookup interface. In these
|
||||
situations, programmers typically resort to manual compositions of different
|
||||
containers, a solution that generally involves a fair amount of code
|
||||
devoted to preserve the synchronization of the different parts of
|
||||
the composition. Boost.MultiIndex allows for the specification of
|
||||
<code>multi_index_container</code>s comprised of one or more <i>indices</i> with
|
||||
different interfaces to the same collection of elements. The resulting constructs
|
||||
are conceptually cleaner than manual compositions, and often perform much better.
|
||||
An important design decision has been taken that the indices of a given
|
||||
<code>multi_index_container</code> instantiation be specified at compile time: this
|
||||
gives ample room for static type checking and code optimization.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex takes inspiration from basic concepts of indexing arising in the
|
||||
theory of relational databases, though it is not intended to provide a full-fledged
|
||||
relational database framework. <code>multi_index_container</code> integrates seamlessly
|
||||
into the STL container/algorithm design, and features some extra capabilities regarding
|
||||
lookup operations and element updating which are useful extensions even for
|
||||
single-indexed containers.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="multi_index_cont_example.png"
|
||||
alt="diagram of a multi_index_container with three indices"
|
||||
width="600" height="304"><br>
|
||||
<b>Fig. 1: Diagram of a <code>multi_index_container</code> with three indices.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The figure above depicts a <code>multi_index_container</code> composed of three indices:
|
||||
the first two present a set-like interface to the elements sorted by
|
||||
shape and id, respectively, while the latter index provides the functionality
|
||||
of a bidirectional list in the spirit of <code>std::list</code>. These
|
||||
indices act as "views" to the internal collection of elements, but they do not only
|
||||
provide read access to the set: insertion/deletion methods are also implemented much
|
||||
as those of <code>std::set</code>s or <code>std::list</code>s. Insertion of an
|
||||
element through one given index will only succeed if the uniqueness constraints of all
|
||||
indices are met.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="namespace">Namespace</a>
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
All the public types of Boost.MultiIndex reside in namespace <code>::boost::multi_index</code>.
|
||||
Additionally, the main class template <code>multi_index_container</code> and global functions
|
||||
<code>get</code> and <code>project</code> are lifted to namespace <code>::boost</code>
|
||||
by means of <code>using</code> declarations. For brevity of exposition, the fragments
|
||||
of code in the documentation are written as if the following declarations were in effect:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>using</span> <span class=keyword>namespace</span> <span class=special>::</span><span class=identifier>boost</span><span class=special>;</span>
|
||||
<span class=keyword>using</span> <span class=keyword>namespace</span> <span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="../index.html"><img src="../prev.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="up_link"><a href="../index.html"><img src="../up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="basics.html"><img src="../next.gif" alt="basics" border="0"><br>
|
||||
Basics
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 21st 2006</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,942 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Tutorial - Index types</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="basics.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="key_extraction.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Index types</h1>
|
||||
|
||||
<div class="prev_link"><a href="basics.html"><img src="../prev.gif" alt="basics" border="0"><br>
|
||||
Basics
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="key_extraction.html"><img src="../next.gif" alt="key estraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#classification">Classification</a>
|
||||
<li><a href="#rnk_indices">Ranked indices</a>
|
||||
<ul>
|
||||
<li><a href="#rnk_spec">Specification</a></li>
|
||||
<li><a href="#rnk_ops">Rank operations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#hashed_indices">Hashed indices</a>
|
||||
<ul>
|
||||
<li><a href="#hash_unique_non_unique">Unique and non-unique variants</a></li>
|
||||
<li><a href="#hash_spec">Specification</a></li>
|
||||
<li><a href="#hash_lookup">Lookup</a></li>
|
||||
<li><a href="#hash_updating">Updating</a></li>
|
||||
<li><a href="#guarantees">Guarantees on iterator validity and exception safety</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#rnd_indices">Random access indices</a>
|
||||
<ul>
|
||||
<li><a href="#rnd_spec">Specification</a></li>
|
||||
<li><a href="#rnd_interface">Interface</a></li>
|
||||
<li><a href="#rnd_vs_vector">Comparison with <code>std::vector</code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#rearrange">Index rearranging</a></li>
|
||||
<li><a href="#iterator_to"><code>iterator_to</code></a></li>
|
||||
<li><a href="#node_handling">Node handling operations</a></li>
|
||||
<li><a href="#ordered_node_compression">Ordered indices node compression</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="classification">Classification</a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex provides eight different index types, which can be classified as
|
||||
shown in the table below. <a href="basics.html#ord_indices">Ordered</a> and
|
||||
<a href="basics.html#seq_indices">sequenced</a> indices,
|
||||
which are the most commonly used, have been explained in the basics section;
|
||||
the rest of index types can be regarded as variations of the former providing
|
||||
some added benefits, functionally or in the area of performance.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<caption><b>Boost.MultiIndex indices.</b></caption>
|
||||
<tr>
|
||||
<th align="center"colspan="2">type</th>
|
||||
<th align="center">specifier</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" rowspan="6"> key-based </td>
|
||||
<td align="center" rowspan="4"> ordered </td>
|
||||
<td align="center"> <code>ordered_unique</code> </td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td align="center"> <code>ordered_non_unique</code> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"> <code>ranked_unique</code> </td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td align="center"> <code>ranked_non_unique</code> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" rowspan="2"> hashed </td>
|
||||
<td align="center"> <code>hashed_unique</code> </td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td align="center"> <code>hashed_non_unique</code> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" rowspan="2" colspan="2"> non key-based </td>
|
||||
<td align="center"><code> sequenced </code></td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td align="center"><code> random_access </code></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Key-based indices, of which ordered indices are the usual example, provide
|
||||
efficient lookup of elements based on some piece of information called the
|
||||
<i>element key</i>: there is an extensive suite of
|
||||
<a href="key_extraction.html">key extraction</a>
|
||||
utility classes allowing for the specification of such keys. Fast lookup
|
||||
imposes an internally managed order on these indices that the user is not
|
||||
allowed to modify; non key-based indices, on the other hand, can be freely
|
||||
rearranged at the expense of lacking lookup facilities. Sequenced indices,
|
||||
modeled after the interface of <code>std::list</code>, are the customary
|
||||
example of a non key-based index.
|
||||
</p>
|
||||
|
||||
<h2><a name="rnk_indices">Ranked indices</a></h2>
|
||||
|
||||
<p>
|
||||
Suppose we have a <code>std::multiset</code> of numbers and we want to output
|
||||
the values above the 75h <a href="http://en.wikipedia.org/wiki/Percentile">percentile</a>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=identifier>int_multiset</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>output_above_75th_percentile</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>int_multiset</span><span class=special>&</span> <span class=identifier>s</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>();</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>advance</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</span><span class=special>()*</span><span class=number>3</span><span class=special>/</span><span class=number>4</span><span class=special>);</span> <span class=comment>// linear on s.size();</span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>copy</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream_iterator</span><span class=special><</span><span class=keyword>int</span><span class=special>>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>,</span><span class=string>"\n"</span><span class=special>));</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The problem with this code is that getting to the beginning of the desired subsequence
|
||||
involves a linear traversal of the container. Ranked indices provide the mechanisms to do this
|
||||
much faster:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ranked_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>int_multiset</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>output_above_75th_percentile</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>int_multiset</span><span class=special>&</span> <span class=identifier>s</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>nth</span><span class=special>(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</span><span class=special>()*</span><span class=number>3</span><span class=special>/</span><span class=number>4</span><span class=special>);</span> <span class=comment>// logarithmic</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>copy</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream_iterator</span><span class=special><</span><span class=keyword>int</span><span class=special>>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>,</span><span class=string>"\n"</span><span class=special>));</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>nth(n)</code> returns an iterator to the element whose <i>rank</i>, i.e. its distance
|
||||
from the beginning of the index, is <code>n</code>, and does so efficiently in logarithmic time.
|
||||
Conversely, <code>rank(it)</code> computes in logarithmic time the rank of the element
|
||||
pointed to by <code>it</code>, or <code>size()</code> if <code>it==end()</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>10</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>size_type</span> <span class=identifier>r</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>it</span><span class=special>);</span> <span class=comment>// rank of 10;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Ranked indices provide the same interface as ordered indices plus several rank-related operations.
|
||||
The cost of this extra functionality is higher memory consumption due to some internal additional
|
||||
data (one word per element) and somewhat longer execution times in insertion and erasure
|
||||
—in particular, erasing an element takes time proportional to <code>log(n)</code>, where
|
||||
<code>n</code> is the number of elements in the index, whereas for ordered indices this time is
|
||||
constant.
|
||||
The <a href="../reference/rnk_indices.html">reference</a> describes these indices in complete detail.
|
||||
</p>
|
||||
|
||||
<h3><a name="rnk_spec">Specification</a></h3>
|
||||
|
||||
<p>
|
||||
The specification of ranked indices is done exactly as with <a href="basics.html#ord_spec">ordered indices</a>,
|
||||
except that <code>ranked_unique</code> and <code>ranked_non_unique</code> are used instead.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)
|
||||
</span><span class=special><[</span><i>(tag)</i><span class=special>[,</span><i>(key extractor)</i><span class=special>[,</span><i>(comparison predicate)</i><span class=special>]]]></span>
|
||||
|
||||
<span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)</span>
|
||||
<span class=special><[</span><i>(key extractor)</i><span class=special>[,</span><i>(comparison predicate)</i><span class=special>]]></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="rnk_ops">Rank operations</a></h3>
|
||||
|
||||
<p>
|
||||
Besides <code>nth</code> and <code>rank</code>, ranked indices provide member functions
|
||||
<ul>
|
||||
<li><code>find_rank</code>,</li>
|
||||
<li><code>lower_bound_rank</code>,</li>
|
||||
<li><code>upper_bound_rank</code>,</li>
|
||||
<li><code>equal_range_rank</code> and </li>
|
||||
<li><code>range_rank</code></li>
|
||||
</ul>
|
||||
that behave as their normal
|
||||
<a href="basics.html#special_lookup">lookup</a> and <a href="basics.html#range">range retrieval</a>
|
||||
counterparts (<code>find</code>, <code>lower_bound</code> etc.) but return ranks rather than iterators.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>void</span> <span class=identifier>percentile</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>int_multiset</span><span class=special>&</span> <span class=identifier>s</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special><<</span><span class=identifier>n</span><span class=special><<</span><span class=string>" lies in the "</span><span class=special><<</span>
|
||||
<span class=identifier>s</span><span class=special>.</span><span class=identifier>upper_bound_rank</span><span class=special>(</span><span class=identifier>n</span><span class=special>)*</span><span class=number>100.0</span><span class=special>/</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</span><span class=special>()<<</span><span class=string>" percentile\n"</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
You might think that <code>upper_bound_rank(n)</code> is mere shorthand for
|
||||
<code>rank(upper_bound(n))</code>: in reality, though, you should prefer using
|
||||
<code>*_rank</code> operations directly as they run faster than the
|
||||
alternative formulations.
|
||||
</p>
|
||||
|
||||
<h2><a name="hashed_indices">Hashed indices</a></h2>
|
||||
|
||||
<p>
|
||||
Hashed indices constitute a trade-off with respect to ordered indices: if correctly used,
|
||||
they provide much faster lookup of elements, at the expense of losing sorting
|
||||
information.
|
||||
Let us revisit our <code>employee_set</code> example: suppose a field for storing
|
||||
the Social Security number is added, with the requisite that lookup by this
|
||||
number should be as fast as possible. Instead of the usual ordered index, a
|
||||
hashed index can be resorted to:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</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>hashed_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>member</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>employee</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>id</span><span class=special>;</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name</span><span class=special>;</span>
|
||||
<span class=keyword>int</span> <span class=identifier>ssnumber</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>employee</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>id</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&</span> <span class=identifier>name</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>ssnumber</span><span class=special>):</span>
|
||||
<span class=identifier>id</span><span class=special>(</span><span class=identifier>id</span><span class=special>),</span><span class=identifier>name</span><span class=special>(</span><span class=identifier>name</span><span class=special>),</span><span class=identifier>ssnumber</span><span class=special>(</span><span class=identifier>ssnumber</span><span class=special>){}</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special><(</span><span class=keyword>const</span> <span class=identifier>employee</span><span class=special>&</span> <span class=identifier>e</span><span class=special>)</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>id</span><span class=special><</span><span class=identifier>e</span><span class=special>.</span><span class=identifier>id</span><span class=special>;}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=comment>// sort by employee::operator<</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> <span class=special>>,</span>
|
||||
|
||||
<span class=comment>// sort by less<string> on name</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>></span> <span class=special>>,</span>
|
||||
|
||||
<span class=comment>// hashed on ssnumber</span>
|
||||
<span class=identifier>hashed_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>employee_set</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Note that the hashed index does not guarantee any particular ordering of the
|
||||
elements: so, for instance, we cannot efficiently query the employees whose SSN is
|
||||
greater than a given number. Usually, you must consider these restrictions when
|
||||
determining whether a hashed index is preferred over an ordered one.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Hashed indices replicate the interface of <code>std::unordered_set</code> and
|
||||
<code>std::unordered_multiset</code>, with only minor differences where required
|
||||
by the general constraints of <code>multi_index_container</code>s, and provide
|
||||
additional useful capabilities like in-place updating of elements.
|
||||
Check the <a href="../reference/hash_indices.html">reference</a> for a
|
||||
complete specification of the interface of hashed indices,
|
||||
and <a href="../examples.html#example8">example 8</a> and
|
||||
<a href="../examples.html#example9">example 9</a> for practical applications.
|
||||
</p>
|
||||
|
||||
</p>
|
||||
|
||||
<h3><a name="hash_unique_non_unique">Unique and non-unique variants</a></h3>
|
||||
|
||||
<p>
|
||||
Just like ordered indices, hashed indices have unique and non-unique variants, selected
|
||||
with the specifiers <code>hashed_unique</code> and <code>hashed_non_unique</code>,
|
||||
respectively. In the latter case, elements with equivalent keys are kept together and can
|
||||
be jointly retrieved by means of the <code>equal_range</code> member function.
|
||||
</p>
|
||||
|
||||
<h3><a name="hash_spec">Specification</a></h3>
|
||||
|
||||
<p>
|
||||
Hashed indices specifiers have two alternative syntaxes, depending on whether
|
||||
<a href="basics.html#tagging">tags</a> are provided or not:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=special>(</span><span class=identifier>hashed_unique</span> <span class=special>|</span> <span class=identifier>hashed_non_unique</span><span class=special>)
|
||||
</span><span class=special><[</span><i>(tag)</i><span class=special>[,</span><i>(key extractor)</i><span class=special>[,</span><i>(hash function)</i><span class=special>[,</span><i>(equality predicate)</i><span class=special>]]]]></span>
|
||||
|
||||
<span class=special>(</span><span class=identifier>hashed_unique</span> <span class=special>|</span> <span class=identifier>hashed_non_unique</span><span class=special>)</span>
|
||||
<span class=special><[</span><i>(key extractor)</i><span class=special>[,</span><i>(hash function)</i><span class=special>[,</span><i>(equality predicate)</i><span class=special>]]]></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The key extractor parameter works in exactly the same way as for
|
||||
<a href="basics.html#key_extraction">ordered indices</a>; lookup, insertion,
|
||||
etc., are based on the key returned by the extractor rather than the whole
|
||||
element.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The hash function is the very core of the fast lookup capabilities of this type of
|
||||
indices: a hasher is just a unary function object
|
||||
returning an <code>std::size_t</code> value for any given
|
||||
key. In general, it is impossible that every key map to a different hash value, for
|
||||
the space of keys can be greater than the number of permissible hash codes: what
|
||||
makes for a good hasher is that the probability of a collision (two different
|
||||
keys with the same hash value) is as close to zero as possible. This is a statistical
|
||||
property depending on the typical distribution of keys in a given application, so
|
||||
it is not feasible to have a general-purpose hash function with excellent results
|
||||
in <i>every</i> possible scenario; the default value for this parameter uses
|
||||
<a href="../../../functional/hash/index.html">Boost.Hash</a>, which often provides good
|
||||
enough results.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The equality predicate is used to determine whether two keys are to be treated
|
||||
as the same. The default
|
||||
value <code>std::equal_to<KeyFromValue::result_type></code> is in most
|
||||
cases exactly what is needed, so very rarely will you have to provide
|
||||
your own predicate. Note that hashed indices require that two
|
||||
equivalent keys have the same hash value, which
|
||||
in practice greatly reduces the freedom in choosing an equality predicate.
|
||||
</p>
|
||||
|
||||
<h3><a name="hash_lookup">Lookup</a></h3>
|
||||
|
||||
<p>
|
||||
The lookup interface of hashed indices consists in member functions
|
||||
<code>find</code>, <code>count</code>, <code>contains</code> and <code>equal_range</code>.
|
||||
Note that <code>lower_bound</code> and <code>upper_bound</code> are not
|
||||
provided, as there is no intrinsic ordering of keys in this type of indices.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Just as with ordered indices, these member functions take keys
|
||||
as their search arguments, rather than entire objects. Remember that
|
||||
ordered indices lookup operations are further augmented to accept
|
||||
<i>compatible keys</i>, which can roughly be regarded as "subkeys".
|
||||
For hashed indices, a concept of
|
||||
<a href="../reference/hash_indices.html#lookup">compatible key</a> is also
|
||||
supported, though its usefulness is much more limited: basically,
|
||||
a compatible key is an object which is entirely equivalent to
|
||||
a native object of <code>key_type</code> value, though maybe with
|
||||
a different internal representation:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// US SSN numbering scheme</span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ssn</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>ssn</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>area_no</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>group_no</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>serial_no</span><span class=special>):</span>
|
||||
<span class=identifier>area_no</span><span class=special>(</span><span class=identifier>area_no</span><span class=special>),</span><span class=identifier>group_no</span><span class=special>(</span><span class=identifier>group_no</span><span class=special>),</span><span class=identifier>serial_no</span><span class=special>(</span><span class=identifier>serial_no</span><span class=special>)</span>
|
||||
<span class=special>{}</span>
|
||||
|
||||
<span class=keyword>int</span> <span class=identifier>to_int</span><span class=special>()</span><span class=keyword>const</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>serial_no</span><span class=special>+</span><span class=number>10000</span><span class=special>*</span><span class=identifier>group_no</span><span class=special>+</span><span class=number>1000000</span><span class=special>*</span><span class=identifier>area_no</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>private</span><span class=special>:</span>
|
||||
<span class=keyword>int</span> <span class=identifier>area_no</span><span class=special>;</span>
|
||||
<span class=keyword>int</span> <span class=identifier>group_no</span><span class=special>;</span>
|
||||
<span class=keyword>int</span> <span class=identifier>serial_no</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=comment>// interoperability with SSNs in raw int form</span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>ssn_equal</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ssn</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>to_int</span><span class=special>()==</span><span class=identifier>y</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>int</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>ssn</span><span class=special>&</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>==</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>to_int</span><span class=special>();</span>
|
||||
<span class=special>}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>ssn_hash</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ssn</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special><</span><span class=keyword>int</span><span class=special>>()(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>to_int</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>int</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special><</span><span class=keyword>int</span><span class=special>>()(</span><span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>2</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>employee_set_by_ssn</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
|
||||
<span class=identifier>employee_set_by_ssn</span><span class=special>&</span> <span class=identifier>ssn_index</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=number>2</span><span class=special>>();</span>
|
||||
<span class=special>...</span>
|
||||
<span class=comment>// find an employee by ssn</span>
|
||||
<span class=identifier>employee</span> <span class=identifier>e</span><span class=special>=*(</span><span class=identifier>ssn_index</span><span class=special>.</span><span class=identifier>find</span><span class=special>(</span><span class=identifier>ssn</span><span class=special>(</span><span class=number>12</span><span class=special>,</span><span class=number>1005</span><span class=special>,</span><span class=number>20678</span><span class=special>),</span><span class=identifier>ssn_hash</span><span class=special>(),</span><span class=identifier>ssn_equal</span><span class=special>()));</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
In the example, we provided a hash functor <code>ssn_hash</code> and an
|
||||
equality predicate <code>ssn_equal</code> allowing for interoperability
|
||||
between <code>ssn</code> objects and the raw <code>int</code>s stored as
|
||||
<code>SSN</code>s in <code>employee_set</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
By far, the most useful application of compatible keys in the context
|
||||
of hashed indices lies in the fact that they allow for seamless usage of
|
||||
<a href="key_extraction.html#composite_keys">composite keys</a>.
|
||||
</p>
|
||||
|
||||
<h3><a name="hash_updating">Updating</a></h3>
|
||||
|
||||
<p>
|
||||
Hashed indices have
|
||||
<a href="../reference/hash_indices.html#replace"><code>replace</code></a>,
|
||||
<a href="../reference/hash_indices.html#modify"><code>modify</code></a> and
|
||||
<a href="../reference/hash_indices.html#modify_key"><code>modify_key</code></a>
|
||||
member functions, with the same functionality as in ordered indices.
|
||||
</p>
|
||||
|
||||
<h3><a name="guarantees">Guarantees on iterator validity and exception safety</a></h3>
|
||||
|
||||
<p>
|
||||
Due to the internal constraints imposed by the Boost.MultiIndex framework,
|
||||
hashed indices provide guarantees on iterator validity and
|
||||
exception safety that are actually stronger than required by the
|
||||
C++ standard with respect to unordered associative containers:
|
||||
<ul>
|
||||
<li>Iterator validity is preserved in any case during insertion or rehashing:
|
||||
C++ unordered associative containers can invalidate iterators when a rehash (implicit or explicit)
|
||||
is performed.</li>
|
||||
<li>Erasing an element or range of elements via iterators does not throw ever,
|
||||
as the internal hash function and equality predicate objects are not actually
|
||||
invoked.</li>
|
||||
<li><code>rehash</code> provides the strong exception safety guarantee
|
||||
unconditionally. The standard only warrants it for unordered associative containers if the internal hash function and
|
||||
equality predicate objects do not throw. The somewhat surprising consequence
|
||||
is that a standard-compliant <code>std::unordered_set</code> might erase
|
||||
elements if an exception is thrown during rehashing!</li>
|
||||
</ul>
|
||||
In general, these stronger guarantees play in favor of the user's convenience,
|
||||
specially that which refers to iterator stability. A (hopefully minimal)
|
||||
degradation in performance might result in exchange for these commodities,
|
||||
though.
|
||||
</p>
|
||||
|
||||
<h2><a name="rnd_indices">Random access indices</a></h2>
|
||||
|
||||
<p>
|
||||
Random access indices offer the same kind of functionality as
|
||||
<a href="basics.html#seq_indices">sequenced indices</a>, with the extra advantages
|
||||
that their iterators are random access, and <code>operator[]</code>
|
||||
and <code>at()</code> are provided for accessing
|
||||
elements based on their position in the index. Let us rewrite a
|
||||
container used in a previous <a href="basics.html#list_fast_lookup">example</a>,
|
||||
using random access instead of sequenced indices:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</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>random_access_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
|
||||
<span class=comment>// text container with fast lookup based on a random access index</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>random_access</span><span class=special><>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>text_container</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// global text container object</span>
|
||||
<span class=identifier>text_container</span> <span class=identifier>tc</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Random access capabilities allow us to efficiently write code
|
||||
like the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>void</span> <span class=identifier>print_page</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>page_num</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>static</span> <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>words_per_page</span><span class=special>=</span><span class=number>50</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>pos0</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>min</span><span class=special>(</span><span class=identifier>tc</span><span class=special>.</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>page_num</span><span class=special>*</span><span class=identifier>words_per_page</span><span class=special>);</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>pos1</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>min</span><span class=special>(</span><span class=identifier>tc</span><span class=special>.</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>pos0</span><span class=special>+</span><span class=identifier>words_per_page</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// note random access iterators can be added offsets</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>copy</span><span class=special>(</span>
|
||||
<span class=identifier>tc</span><span class=special>.</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>pos0</span><span class=special>,</span><span class=identifier>tc</span><span class=special>.</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>pos1</span><span class=special>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream_iterator</span><span class=special><</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>));</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>print_random_word</span><span class=special>()</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special><<</span><span class=identifier>tc</span><span class=special>[</span><span class=identifier>rand</span><span class=special>()%</span><span class=identifier>tc</span><span class=special>.</span><span class=identifier>size</span><span class=special>()];</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
This added flexibility comes at a price: insertions and deletions at positions
|
||||
other than the end of the index have linear complexity, whereas these operations
|
||||
are constant time for sequenced indices. This situation is reminiscent of the
|
||||
differences in complexity behavior between <code>std::list</code> and
|
||||
<code>std::vector</code>: in the case of random access indices, however,
|
||||
insertions and deletions never incur any element copying, so the actual
|
||||
performance of these operations can be acceptable, despite the theoretical
|
||||
disadvantage with respect to sequenced indices.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="../examples.html#example10">Example 10</a> and
|
||||
<a href="../examples.html#example11">example 11</a> in the examples section put
|
||||
random access indices in practice.
|
||||
</p>
|
||||
|
||||
<h3><a name="rnd_spec">Specification</a></h3>
|
||||
|
||||
<p>
|
||||
Random access indices are specified with the <code>random_access</code> construct,
|
||||
where the <a href="basics.html#tagging">tag</a> parameter is, as usual, optional:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>random_access</span><span class=special><[</span><i>(tag)</i><span class=special>]></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="rnd_interface">Interface</a></h3>
|
||||
|
||||
<p>
|
||||
All public functions offered by sequenced indices are also provided
|
||||
by random access indices, so that the latter can act as a drop-in replacement
|
||||
of the former (save with respect to their complexity bounds, as explained above).
|
||||
Besides, random access
|
||||
indices have <code>operator[]</code> and <code>at()</code> for positional
|
||||
access to the elements, and member functions
|
||||
<a href="../reference/rnd_indices.html#capacity_memfun"><code>capacity</code></a> and
|
||||
<a href="../reference/rnd_indices.html#reserve"><code>reserve</code></a>
|
||||
that control internal reallocation in a similar manner as the homonym
|
||||
facilities in <code>std::vector</code>. Check the
|
||||
<a href="../reference/rnd_indices.html">reference</a> for details.
|
||||
</p>
|
||||
|
||||
<h3><a name="rnd_vs_vector">Comparison with <code>std::vector</code></a></h3>
|
||||
|
||||
<p>
|
||||
It is tempting to see random access indices as an analogue of <code>std::vector</code>
|
||||
for use in Boost.MultiIndex, but this metaphor can be misleading, as both constructs,
|
||||
though similar in many respects, show important semantic differences. An
|
||||
advantage of random access indices is that their iterators, as well as references
|
||||
to their elements, are <i>stable</i>, that is, they remain valid after any insertions
|
||||
or deletions. On the other hand, random access indices have several disadvantages with
|
||||
respect to <code>std::vector</code>s:
|
||||
<ul>
|
||||
<li>They do not provide <i>memory contiguity</i>, a property
|
||||
of <code>std::vector</code>s by which elements are stored adjacent to one
|
||||
another in a single block of memory.
|
||||
</li>
|
||||
<li>As usual in Boost.MultiIndex, elements of random access indices are immutable
|
||||
and can only be modified through member functions
|
||||
<a href="../reference/rnd_indices.html#replace"><code>replace</code></a> and
|
||||
<a href="../reference/rnd_indices.html#modify"><code>modify</code></a>.
|
||||
This precludes the usage of many mutating
|
||||
algorithms that are nonetheless applicable to <code>std::vector</code>s.
|
||||
</li>
|
||||
</ul>
|
||||
The latter shortcoming can be partially remedied by means of the
|
||||
<a href="#rearrange">rearranging interface</a> these indices provide.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In general, it is more instructive to regard random access indices as
|
||||
a variation of sequenced indices providing random access semantics, instead
|
||||
of insisting on the <code>std::vector</code> analogy.
|
||||
</p>
|
||||
|
||||
<h2><a name="rearrange">Index rearranging</a></h2>
|
||||
|
||||
<p>
|
||||
By design, index elements are immutable, i.e. iterators only grant
|
||||
<code>const</code> access to them, and only through the provided
|
||||
updating interface (<code>replace</code>, <code>modify</code> and
|
||||
<code>modify_key</code>) can the elements be modified. This restriction
|
||||
is set up so that the internal invariants of key-based indices are
|
||||
not broken (for instance, ascending order traversal in ordered
|
||||
indices), but induces important limitations in non key-based indices:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>random_access</span><span class=special><>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>container</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>container</span> <span class=identifier>c</span><span class=special>;</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>mt19937</span> <span class=identifier>rng</span><span class=special>;</span>
|
||||
<span class=special>...</span>
|
||||
<span class=comment>// compiler error: assignment to read-only objects</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>shuffle</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>rng</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
What is unfortunate about the previous example is that the operation
|
||||
performed by <code>std::shuffle</code> is potentially compatible
|
||||
with <code>multi_index_container</code> invariants, as its result can be
|
||||
described by a permutation of the elements in the random access index
|
||||
with no actual modifications to the elements themselves. There are many
|
||||
more examples of such compatible algorithms in the C++ standard library,
|
||||
like for instance all sorting and partition functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sequenced and random access indices provide a means to take advantage
|
||||
of such external algorithms. In order to introduce this facility we need
|
||||
a preliminary concept: a <i>view</i> of an index is defined as
|
||||
some iterator range [<code>first</code>,<code>last</code>) over the
|
||||
elements of the index such that all its elements are contained in the
|
||||
range exactly once. Continuing with our example, we can apply
|
||||
<code>std::shuffle</code> on an ad hoc view obtained from the
|
||||
container:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// note that the elements of the view are not copies of the elements
|
||||
// in c, but references to them</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special><</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>reference_wrapper</span><span class=special><</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>></span> <span class=special>></span> <span class=identifier>v</span><span class=special>;</span>
|
||||
<span class=identifier>BOOST_FOREACH</span><span class=special>(</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&</span> <span class=identifier>i</span><span class=special>,</span><span class=identifier>c</span><span class=special>)</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>push_back</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>cref</span><span class=special>(</span><span class=identifier>i</span><span class=special>));</span>
|
||||
|
||||
<span class=comment>// this compiles OK, as reference_wrappers are swappable</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>shuffle</span><span class=special>(</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>rng</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Elements of <code>v</code> are <code>reference_wrapper</code>s (from
|
||||
<a href="../../../../doc/html/ref.html">Boost.Ref</a>) to the actual elements
|
||||
in the multi-index container. These objects still do not allow modification
|
||||
of the referenced entities, but they are swappable,
|
||||
which is the only requirement <code>std::shuffle</code> imposes. Once
|
||||
we have our desired rearrange stored in the view, we can transfer it to
|
||||
the container with
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>rearrange</code> accepts an input iterator signaling the beginning
|
||||
of the external view (and end iterator is not needed since the length of
|
||||
the view is the same as that of the index) and internally relocates the
|
||||
elements of the index so that their traversal order matches the view.
|
||||
Albeit with some circumventions, <code>rearrange</code> allows for the
|
||||
application of a varied range of algorithms to non key-based indices.
|
||||
Please note that the view concept is very general, and in no way tied
|
||||
to the particular implementation example shown above. For instance, indices
|
||||
of a <code>multi_index_container</code> are indeed views with respect to
|
||||
its non key-based indices:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// rearrange as index #1 (ascending order)</span>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=number>1</span><span class=special>>().</span><span class=identifier>begin</span><span class=special>());</span>
|
||||
|
||||
<span class=comment>// rearrange in descending order</span>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=number>1</span><span class=special>>().</span><span class=identifier>rbegin</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The only important requirement imposed on views is that they must be
|
||||
<i>free</i>, i.e. they are not affected by relocations on the base index:
|
||||
thus, <code>rearrange</code> does not accept the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// undefined behavior: [rbegin(),rend()) is not free with respect
|
||||
// to the base index</span>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>rbegin</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The view concept is defined in detail in the
|
||||
<a href="../reference/indices.html#views">reference</a>.
|
||||
See <a href="../examples.html#example11">example 11</a> in the examples section
|
||||
for a demonstration of use of <code>rearrange</code>.
|
||||
</p>
|
||||
|
||||
<h2><a name="iterator_to"><code>iterator_to</code></a></h2>
|
||||
|
||||
<p>
|
||||
All indices of Boost.MultiIndex provide a member function called <code>iterator_to</code>
|
||||
which returns an iterator to a given element of the container:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>c</span><span class=special>;</span>
|
||||
<span class=special>...</span>
|
||||
<span class=comment>// convoluted way to do c.pop_back()</span>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>iterator_to</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>back</span><span class=special>()));</span>
|
||||
|
||||
<span class=comment>// The following, though similar to the previous code,
|
||||
// does not work: iterator_to accepts a reference to
|
||||
// the element in the container, not a copy.</span>
|
||||
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>back</span><span class=special>();</span>
|
||||
<span class=identifier>c</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>iterator_to</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// run-time failure ensues</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>iterator_to</code> provides a way to retrieve an iterator to an element
|
||||
from a pointer to the element, thus making iterators and pointers interchangeable
|
||||
for the purposes of element pointing (not so for traversal) in many situations.
|
||||
This notwithstanding, it is not the aim of <code>iterator_to</code> to
|
||||
promote the usage of pointers as substitutes for real iterators: the latter are
|
||||
specifically designed for handling the elements of a container,
|
||||
and not only benefit from the iterator orientation of container interfaces,
|
||||
but are also capable of exposing many more programming bugs than raw pointers, both
|
||||
at compile and run time. <code>iterator_to</code> is thus meant to be used
|
||||
in scenarios where access via iterators is not suitable or desirable:
|
||||
<ul>
|
||||
<li>Interoperability with preexisting APIs based on pointers or references.</li>
|
||||
<li>Publication of pointer-based interfaces (for instance, when
|
||||
designing a C-compatible library).
|
||||
</li>
|
||||
<li>The exposure of pointers in place of iterators can act as a <i>type
|
||||
erasure</i> barrier effectively decoupling the user of the code
|
||||
from the implementation detail of which particular container is being
|
||||
used. Similar techniques, like the famous Pimpl idiom, are used
|
||||
in large projects to reduce dependencies and build times.
|
||||
</li>
|
||||
<li>Self-referencing contexts where an element acts upon its owner
|
||||
container and no iterator to itself is available.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="node_handling">Node handling operations</a></h2>
|
||||
|
||||
<p>
|
||||
Using direct node manipulation, elements can be passed between
|
||||
<code>multi_index_container</code>s without actually copying them:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// move an employee to the retiree archive</span>
|
||||
<span class=keyword>void</span> <span class=identifier>move_to_retirement</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>ssnumber</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>es</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</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><</span><span class=identifier>ssn</span><span class=special>>().</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><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>sequenced</span><span class=special><>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>src</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>sequenced</span><span class=special><>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>>,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></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>&</span> <span class=identifier>es</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</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>&</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><</span><span class=identifier>age</span><span class=special>>();</span>
|
||||
|
||||
<span class=comment>// archive employees with age>max_age</span>
|
||||
<span class=identifier>archive</span><span class=special>.</span><span class=identifier>merge</span><span class=special>(</span><span class=identifier>ea</span><span class=special>,</span><span class=identifier>ea</span><span class=special>.</span><span class=identifier>upper_bound</span><span class=special>(</span><span class=identifier>max_age</span><span class=special>),</span><span class=identifier>ea</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=comment>// transfer even numbers from src to dst</span>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=keyword>auto</span> <span class=identifier>first</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>last</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>;){</span>
|
||||
<span class=keyword>if</span><span class=special>(*</span><span class=identifier>first</span><span class=special>%</span><span class=number>2</span><span class=special>==</span><span class=number>0</span><span class=special>)</span> <span class=identifier>dst</span><span class=special>.</span><span class=identifier>splice</span><span class=special>(</span><span class=identifier>dst</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>src</span><span class=special>,</span><span class=identifier>first</span><span class=special>++);</span>
|
||||
<span class=keyword>else</span> <span class=special>++</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
There are overloads of <code>merge</code>/<code>splice</code> for transferring a single element,
|
||||
a range between two iterators and an entire container: for further details, consult
|
||||
for instance the reference for <a href="../reference/ord_indices.html#merge">ordered indices</a> and for
|
||||
<a href="../reference/seq_indices.html#splice">sequenced indices</a>
|
||||
(the rest of indices provide one interface or the other).
|
||||
Please note that sequenced and random access indices do also have an operation called <code>merge</code>,
|
||||
but this follows the specification of <code>std::list::merge</code>, which has a somewhat
|
||||
different behavior (source and destination are required to be ordered by the same criterion). This is
|
||||
a rather confusing naming issue that Boost.MultiIndex simply inherits from the C++ standard.
|
||||
</p>
|
||||
|
||||
<h2><a name="ordered_node_compression">Ordered indices node compression</a></h2>
|
||||
|
||||
<p>
|
||||
Ordered and ranked indices are implemented by means of a data structure
|
||||
known as a <i>red-black tree</i>. Nodes of a red-back tree contain pointers
|
||||
to the parent and the two children nodes, plus a 1-bit field referred to as
|
||||
the <i>node color</i> (hence the name of the structure). Due to alignment
|
||||
issues, on most architectures the color field occupies one entire word, that is,
|
||||
4 bytes in 32-bit systems and 8 bytes in 64-bit environments. This waste
|
||||
of space can be avoided by embedding the color bit inside one of the
|
||||
node pointers, provided not all the bits of the pointer representation contain
|
||||
useful information: this is precisely the case in many architectures where
|
||||
such nodes are aligned to even addresses, which implies that the least
|
||||
significant bit of the address must always be zero.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex ordered and ranked indices implement this type of node compression
|
||||
whenever applicable. As compared with common implementations of the STL
|
||||
container <code>std::set</code>, node compression can
|
||||
result in a reduction of header overload by 25% (from 16 to 12 bytes on
|
||||
typical 32-bit architectures, and from 32 to 24 bytes on 64-bit systems).
|
||||
The impact on performance of this optimization has been checked to be negligible
|
||||
for moderately sized containers, whereas containers with many elements (hundreds
|
||||
of thousands or more) perform faster with this optimization, most likely due to
|
||||
L1 and L2 cache effects.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Node compression can be disabled by globally setting the macro
|
||||
<code>BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES</code>.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="basics.html"><img src="../prev.gif" alt="basics" border="0"><br>
|
||||
Basics
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="key_extraction.html"><img src="../next.gif" alt="key estraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
@@ -0,0 +1,409 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Tutorial - Techniques</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
<link rel="start" href="../index.html">
|
||||
<link rel="prev" href="debug.html">
|
||||
<link rel="up" href="index.html">
|
||||
<link rel="next" href="../reference/index.html">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Tutorial: Techniques</h1>
|
||||
|
||||
<div class="prev_link"><a href="debug.html"><img src="../prev.gif" alt="debugging support" border="0"><br>
|
||||
Debugging support
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="../reference/index.html"><img src="../next.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#emulate_std_containers">Emulating standard containers with
|
||||
<code>multi_index_container</code></a>
|
||||
<ul>
|
||||
<li><a href="#emulate_assoc_containers">Emulation of associative
|
||||
containers</a></li>
|
||||
<li><a href="#emulate_std_list">Emulation of <code>std::list</code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#metaprogrammming">Metaprogramming and <code>multi_index_container</code></a>
|
||||
<ul>
|
||||
<li><a href="#analysis">Analysis</a></li>
|
||||
<li><a href="#synthesis">Synthesis</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="emulate_std_containers">Emulating standard containers with
|
||||
<code>multi_index_container</code></a></h2>
|
||||
|
||||
<h3><a name="emulate_assoc_containers">Emulation of associative
|
||||
containers</a></h3>
|
||||
|
||||
<p>
|
||||
Academic motivations aside, there is a practical interest in emulating standard
|
||||
associative containers by means of <code>multi_index_container</code>, namely to take
|
||||
advantage of extended functionalities provided by <code>multi_index_container</code> for
|
||||
lookup, range querying and updating.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In order to emulate a <code>std::set</code> one can follow the substitution
|
||||
rule:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>Key</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>Key</span><span class=special>>,</span><span class=identifier>Compare</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
In the default case where <code>Compare=std::less<Key></code> and
|
||||
<code>Allocator=std::allocator<Key></code>, the substitution rule is
|
||||
simplified as
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=identifier>Key</span><span class=special>></span> <span class=special>-></span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Key</span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The substitution of <code>multi_index_container</code> for <code>std::set</code> keeps
|
||||
the whole set of functionality provided by <code>std::set</code>, so in
|
||||
principle it is a drop-in replacement needing no further adjustments.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>std::multiset</code> can be emulated in a similar manner, according to the
|
||||
following rule:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>Key</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>Key</span><span class=special>>,</span><span class=identifier>Compare</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
When default values are taken into consideration, the rule takes the form
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special><</span><span class=identifier>Key</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>Key</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>Key</span><span class=special>></span> <span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The emulation of <code>std::multiset</code>s with <code>multi_index_container</code>
|
||||
results in a slight difference with respect to the interface offered: the member
|
||||
function <code>insert(const value_type&)</code> does not return an
|
||||
<code>iterator</code> as in <code>std::multiset</code>s, but rather a
|
||||
<code>std::pair<iterator,bool></code> in the spirit of <code>std::set</code>s.
|
||||
In this particular case, however, the <code>bool</code> member of the returned
|
||||
pair is always <code>true</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The case of <code>std::map</code>s and <code>std::multimap</code>s does not lend
|
||||
itself to such a direct emulation by means of <code>multi_index_container</code>. The main
|
||||
problem lies in the fact that elements of a <code>multi_index_container</code> are treated
|
||||
as constant, while the <code>std::map</code> and <code>std::multimap</code> handle
|
||||
objects of type <code>std::pair<const Key,T></code>, thus allowing for free
|
||||
modification of the value part. To overcome this difficulty we need to create an ad
|
||||
hoc pair class:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span> <span class=identifier>T1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>T2</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>mutable_pair</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>T1</span> <span class=identifier>first_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>T2</span> <span class=identifier>second_type</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>mutable_pair</span><span class=special>():</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>T1</span><span class=special>()),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>T2</span><span class=special>()){}</span>
|
||||
<span class=identifier>mutable_pair</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>T1</span><span class=special>&</span> <span class=identifier>f</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>T2</span><span class=special>&</span> <span class=identifier>s</span><span class=special>):</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>f</span><span class=special>),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>s</span><span class=special>){}</span>
|
||||
<span class=identifier>mutable_pair</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>T1</span><span class=special>,</span><span class=identifier>T2</span><span class=special>>&</span> <span class=identifier>p</span><span class=special>):</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>first</span><span class=special>),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>second</span><span class=special>){}</span>
|
||||
|
||||
<span class=identifier>T1</span> <span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=keyword>mutable</span> <span class=identifier>T2</span> <span class=identifier>second</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
and so the substitution rules are:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>map</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>Element</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>>,</span><span class=identifier>Compare</span><span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special><</span><span class=identifier>Element</span><span class=special>>::</span><span class=identifier>other</span>
|
||||
<span class=special>></span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>multimap</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>Element</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>>,</span><span class=identifier>Compare</span><span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special><</span><span class=identifier>Element</span><span class=special>>::</span><span class=identifier>other</span>
|
||||
<span class=special>></span>
|
||||
|
||||
(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_pair</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>></span>)
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
If default values are considered, the rules take the form:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>map</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>Element</span><span class=special>,
|
||||
</span><span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>></span> <span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>multimap</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>Element</span><span class=special>,
|
||||
</span><span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>></span> <span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
|
||||
(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_pair</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>></span>)
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Unlike as with standard sets, the interface of these <code>multi_index_container</code>-emulated
|
||||
maps does not exactly conform to that of <code>std::map</code>s and
|
||||
<code>std::multimap</code>s. The most obvious difference is the lack of
|
||||
<code>operator []</code>, either in read or write mode; this, however, can be
|
||||
emulated with appropriate use of <code>find</code> and <code>insert</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These emulations of standard associative containers with <code>multi_index_container</code>
|
||||
are comparable to the original constructs in terms of space and time efficiency.
|
||||
See the <a href="../performance.html">performance section</a> for further details.
|
||||
</p>
|
||||
|
||||
<h3><a name="emulate_std_list">Emulation of <code>std::list</code></a></h3>
|
||||
|
||||
<p>
|
||||
Unlike the case of associative containers, emulating <code>std::list</code>
|
||||
in Boost.MultiIndex does not add any significant functionality, so the following
|
||||
is presented merely for completeness sake.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Much as with standard maps, the main difficulty to overcome when emulating
|
||||
<code>std::list</code> derives from the constant nature of elements of a
|
||||
<code>multi_index_container</code>. Again, some sort of adaption class is needed, like
|
||||
for instance the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span> <span class=identifier>T</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>mutable_value</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>mutable_value</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>T</span><span class=special>&</span> <span class=identifier>t</span><span class=special>):</span><span class=identifier>t</span><span class=special>(</span><span class=identifier>t</span><span class=special>){}</span>
|
||||
<span class=keyword>operator</span> <span class=identifier>T</span><span class=special>&()</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>t</span><span class=special>;}</span>
|
||||
|
||||
<span class=keyword>private</span><span class=special>:</span>
|
||||
<span class=keyword>mutable</span> <span class=identifier>T</span> <span class=identifier>t</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
which allows us to use the substitution rule:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special><</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>Element</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special><</span><span class=identifier>Element</span><span class=special>>::</span><span class=identifier>other</span>
|
||||
<span class=special>></span>
|
||||
|
||||
(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_value</span><span class=special><</span><span class=identifier>T</span><span class=special>></span>)
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
or, if the default value <code>Allocator=std::allocator<T></code> is used:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special><</span><span class=identifier>T</span><span class=special>></span> <span class=special>-></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>mutable_value</span><span class=special><</span><span class=identifier>T</span><span class=special>>,</span><span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span> <span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h2><a name="metaprogrammming">Metaprogramming and <code>multi_index_container</code></a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex provides a number of facilities intended to allow the analysis and
|
||||
synthesis of <code>multi_index_container</code> instantiations with metaprogramming.
|
||||
</p>
|
||||
|
||||
<h3><a name="analysis">Analysis</a></h3>
|
||||
|
||||
<p>
|
||||
Given a <code>multi_index_container</code> instantiation, the following nested types are
|
||||
provided for compile-time inspection of the various types occurring in the
|
||||
definition of the <code>multi_index_container</code>:
|
||||
<ul>
|
||||
<li><code>index_specifier_type_list</code>,</li>
|
||||
<li><code>index_type_list</code>,</li>
|
||||
<li><code>iterator_type_list</code>,</li>
|
||||
<li><code>const_iterator_type_list</code>.</li>
|
||||
</ul>
|
||||
Each of these types is an
|
||||
<a href="../../../../libs/mp11/doc/html/mp11.html#definitions">Mp11 list</a>
|
||||
with as many elements as indices
|
||||
comprise the <code>multi_index_container</code>: for instance, the <code>n</code>-th
|
||||
element of <code>iterator_type_list</code> is the same as
|
||||
<code>nth_index<n>::type::iterator</code>. Boost.Mp11 makes it very easy
|
||||
to inspect and manipulate these lists:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>using</span> <span class=identifier>indexed_t</span><span class=special>=</span><span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>sequenced</span><span class=special><></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>>;</span>
|
||||
|
||||
<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><</span><span class=identifier>indexed_t</span><span class=special>::</span><span class=identifier>index_specifier_type_list</span><span class=special>>([](</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><<</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><</span><span class=identifier>decltype</span><span class=special>(</span><span class=identifier>I</span><span class=special>)>().</span><span class=identifier>pretty_name</span><span class=special>()</span> <span class=special><<</span> <span class=string>"\n"</span><span class=special>;</span>
|
||||
<span class=special>});</span>
|
||||
|
||||
<span class=comment>// Output:
|
||||
//
|
||||
// struct boost::multi_index::ordered_unique<struct boost::multi_index::identity<int>,void,void>
|
||||
// struct boost::multi_index::sequenced<struct boost::multi_index::tag<> ></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><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span><span class=special>></span>
|
||||
<span class=identifier>sequenced</span><span class=special><></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
while <code>indexed_t::index_type_list</code> holds the types
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special>::</span><span class=identifier>nth_type</span><span class=special><</span><span class=number>0</span><span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>::</span><span class=identifier>nth_type</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
so the lists are radically different.
|
||||
</p>
|
||||
|
||||
<h3><a name="synthesis">Synthesis</a></h3>
|
||||
|
||||
<p>
|
||||
Although typically indices are specified by means of the
|
||||
<code>indexed_by</code> construct, actually any Mp11 list can be provided instead:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>using</span> <span class=identifier>index_list_t</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>tuple</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span><span class=identifier>sequenced</span><span class=special><>></span> <span class=special>;</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>index_list_t</span>
|
||||
<span class=special>></span> <span class=identifier>indexed_t</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
This possibility enables the synthesis of instantiations of
|
||||
<code>multi_index_container</code> through metaprogramming, as the following
|
||||
example shows:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// original multi_index_container instantiation</span>
|
||||
<span class=keyword>using</span> <span class=identifier>indexed_t1</span><span class=special>=</span><span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>>;</span>
|
||||
|
||||
<span class=comment>// we take its index list and add an index</span>
|
||||
<span class=keyword>using</span> <span class=identifier>index_list_t2</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>mp11</span><span class=special>::</span><span class=identifier>mp_push_front</span><span class=special><</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><></span>
|
||||
<span class=special>>;</span>
|
||||
|
||||
<span class=comment>// augmented multi_index_container</span>
|
||||
<span class=keyword>using</span> <span class=identifier>indexed_t2</span><span class=special>=</span><span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>index_list_t2</span>
|
||||
<span class=special>>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="debug.html"><img src="../prev.gif" alt="debugging support" border="0"><br>
|
||||
Debugging support
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
|
||||
Boost.MultiIndex tutorial
|
||||
</a></div>
|
||||
<div class="next_link"><a href="../reference/index.html"><img src="../next.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised October 25th 2025</p>
|
||||
|
||||
<p>© Copyright 2003-2025 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,57 +1,66 @@
|
||||
# Boost.MultiIndex examples Jamfile
|
||||
#
|
||||
# Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
# Copyright 2003-2007 Joaqu�n M L�pez Mu�oz.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/multi_index for library home page.
|
||||
|
||||
subproject libs/multi_index/example ;
|
||||
project : requirements <library>/boost/multi_index//boost_multi_index ;
|
||||
|
||||
exe basic
|
||||
: basic.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe bimap
|
||||
: bimap.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe complex_structs
|
||||
: complex_structs.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe composite_keys
|
||||
: composite_keys.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
/boost/tokenizer//boost_tokenizer
|
||||
;
|
||||
|
||||
exe fun_key
|
||||
: fun_key.cpp
|
||||
;
|
||||
|
||||
exe hashed
|
||||
: hashed.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
/boost/tokenizer//boost_tokenizer
|
||||
;
|
||||
|
||||
exe memfun_key
|
||||
: memfun_key.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
exe ip_allocator
|
||||
: ip_allocator.cpp
|
||||
/boost/interprocess//boost_interprocess
|
||||
: <threading>multi
|
||||
;
|
||||
|
||||
exe non_default_ctor
|
||||
: non_default_ctor.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe random_access
|
||||
: random_access.cpp
|
||||
/boost/tokenizer//boost_tokenizer
|
||||
;
|
||||
|
||||
exe rearrange
|
||||
: rearrange.cpp
|
||||
/boost/random//boost_random
|
||||
;
|
||||
|
||||
exe sequenced
|
||||
: sequenced.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
/boost/tokenizer//boost_tokenizer
|
||||
;
|
||||
|
||||
exe serialization
|
||||
: serialization.cpp
|
||||
<lib>../../serialization/build/boost_serialization
|
||||
: <include>$(BOOST_ROOT)
|
||||
std::locale-support
|
||||
/boost/serialization//boost_serialization
|
||||
;
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex basic example.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -47,12 +47,8 @@ struct id{};
|
||||
struct name{};
|
||||
struct age{};
|
||||
|
||||
/* see Compiler specifics: Use of member_offset for info on
|
||||
* BOOST_MULTI_INDEX_MEMBER
|
||||
*/
|
||||
|
||||
/* Define a multi_index_container of employees with following indices:
|
||||
* - a unique index sorted by employee::int,
|
||||
* - a unique index sorted by employee::id,
|
||||
* - a non-unique index sorted by employee::name,
|
||||
* - a non-unique index sorted by employee::age.
|
||||
*/
|
||||
@@ -61,18 +57,15 @@ typedef multi_index_container<
|
||||
employee,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
|
||||
tag<id>, member<employee,int,&employee::id> >,
|
||||
ordered_non_unique<
|
||||
tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
|
||||
tag<name>,member<employee,std::string,&employee::name> >,
|
||||
ordered_non_unique<
|
||||
tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >
|
||||
tag<age>, member<employee,int,&employee::age> > >
|
||||
> employee_set;
|
||||
|
||||
template<typename Tag,typename MultiIndexContainer>
|
||||
void print_out_by(
|
||||
const MultiIndexContainer& s,
|
||||
Tag* =0 /* fixes a MSVC++ 6.0 bug with implicit template function parms */
|
||||
)
|
||||
void print_out_by(const MultiIndexContainer& s)
|
||||
{
|
||||
/* obtain a reference to the index tagged by Tag */
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of a bidirectional map.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
@@ -35,31 +34,15 @@ struct to{};
|
||||
template<typename FromType,typename ToType>
|
||||
struct bidirectional_map
|
||||
{
|
||||
typedef std::pair<FromType,ToType> value_type;
|
||||
struct value_type
|
||||
{
|
||||
value_type(const FromType& first_,const ToType& second_):
|
||||
first(first_),second(second_)
|
||||
{}
|
||||
|
||||
#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) ||\
|
||||
defined(BOOST_MSVC)&&(BOOST_MSVC<1300) ||\
|
||||
defined(BOOST_INTEL_CXX_VERSION)&&defined(_MSC_VER)&&\
|
||||
(BOOST_INTEL_CXX_VERSION<=700)
|
||||
|
||||
/* see Compiler specifics: Use of member_offset for info on member<> and
|
||||
* member_offset<>
|
||||
*/
|
||||
|
||||
BOOST_STATIC_CONSTANT(unsigned,from_offset=offsetof(value_type,first));
|
||||
BOOST_STATIC_CONSTANT(unsigned,to_offset =offsetof(value_type,second));
|
||||
|
||||
typedef multi_index_container<
|
||||
value_type,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
tag<from>,member_offset<value_type,FromType,from_offset> >,
|
||||
ordered_unique<
|
||||
tag<to>, member_offset<value_type,ToType,to_offset> >
|
||||
>
|
||||
> type;
|
||||
|
||||
#else
|
||||
FromType first;
|
||||
ToType second;
|
||||
};
|
||||
|
||||
/* A bidirectional map can be simulated as a multi_index_container
|
||||
* of pairs of (FromType,ToType) with two unique indices, one
|
||||
@@ -75,8 +58,6 @@ struct bidirectional_map
|
||||
tag<to>, member<value_type,ToType,&value_type::second> >
|
||||
>
|
||||
> type;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
/* a dictionary is a bidirectional map from strings to strings */
|
||||
@@ -101,22 +82,6 @@ int main()
|
||||
std::string word;
|
||||
std::getline(std::cin,word);
|
||||
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) /* use global get<> and family instead */
|
||||
|
||||
dictionary::iterator it=get<from>(d).find(word);
|
||||
if(it!=d.end()){
|
||||
std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
|
||||
}
|
||||
else{
|
||||
nth_index_iterator<dictionary,1>::type it2=get<1>(d).find(word);
|
||||
if(it2!=get<1>(d).end()){
|
||||
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
|
||||
}
|
||||
else std::cout<<"No such word in the dictionary"<<std::endl;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* search the queried word on the from index (Spanish) */
|
||||
|
||||
dictionary::iterator it=d.get<from>().find(word);
|
||||
@@ -129,14 +94,12 @@ int main()
|
||||
else{
|
||||
/* word not found in Spanish, try our luck in English */
|
||||
|
||||
dictionary::index_iterator<to>::type it2=d.get<to>().find(word);
|
||||
dictionary::index<to>::type::iterator it2=d.get<to>().find(word);
|
||||
if(it2!=d.get<to>().end()){
|
||||
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
|
||||
}
|
||||
else std::cout<<"No such word in the dictionary"<<std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example: complex searches and foreign keys.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -88,10 +88,6 @@ struct car_model
|
||||
}
|
||||
};
|
||||
|
||||
/* see Compiler specifics: Use of member_offset for info on
|
||||
* BOOST_MULTI_INDEX_MEMBER
|
||||
*/
|
||||
|
||||
/* Car manufacturers are stored in a multi_index_container with one single
|
||||
* index on the name member. This is functionally equivalent to an std::set,
|
||||
* though in this latter case we woud have to define a non-default comparison
|
||||
@@ -102,7 +98,7 @@ typedef multi_index_container<
|
||||
car_manufacturer,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
BOOST_MULTI_INDEX_MEMBER(car_manufacturer,std::string,name)
|
||||
member<car_manufacturer,std::string,&car_manufacturer::name>
|
||||
>
|
||||
>
|
||||
> car_manufacturer_table;
|
||||
@@ -118,18 +114,18 @@ typedef multi_index_container<
|
||||
car_model,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
tag<model>,BOOST_MULTI_INDEX_MEMBER(car_model,std::string,model)
|
||||
tag<model>,member<car_model,std::string,&car_model::model>
|
||||
>,
|
||||
ordered_non_unique<
|
||||
tag<manufacturer>,
|
||||
key_from_key<
|
||||
BOOST_MULTI_INDEX_MEMBER(car_manufacturer,const std::string,name),
|
||||
BOOST_MULTI_INDEX_MEMBER(
|
||||
car_model,const car_manufacturer *,manufacturer)
|
||||
member<car_manufacturer,const std::string,&car_manufacturer::name>,
|
||||
member<
|
||||
car_model,const car_manufacturer *,&car_model::manufacturer>
|
||||
>
|
||||
>,
|
||||
ordered_non_unique<
|
||||
tag<price>,BOOST_MULTI_INDEX_MEMBER(car_model,int,price)
|
||||
tag<price>,member<car_model,int,&car_model::price>
|
||||
>
|
||||
>
|
||||
> car_table;
|
||||
@@ -138,7 +134,7 @@ typedef multi_index_container<
|
||||
* actual objects. These views are used in the complex search performed
|
||||
* in the program. Resorting to multi_index of pointers eliminates
|
||||
* unnecessary copying of objects, and provides us with an opportunity
|
||||
* to show how BOOST_MULTI_INDEX_MEMBER can be used with pointer
|
||||
* to show how boost::multi_index::member can be used with pointer
|
||||
* type elements.
|
||||
* car_table_price_view indexes (pointers to) car_models by price.
|
||||
*/
|
||||
@@ -146,7 +142,7 @@ typedef multi_index_container<
|
||||
typedef multi_index_container<
|
||||
const car_model*,
|
||||
indexed_by<
|
||||
ordered_non_unique<BOOST_MULTI_INDEX_MEMBER(car_model,const int,price)>
|
||||
ordered_non_unique<member<car_model,const int,&car_model::price> >
|
||||
>
|
||||
> car_table_price_view;
|
||||
|
||||
@@ -159,9 +155,9 @@ typedef multi_index_container<
|
||||
indexed_by<
|
||||
ordered_non_unique<
|
||||
key_from_key<
|
||||
BOOST_MULTI_INDEX_MEMBER(car_manufacturer,const std::string,name),
|
||||
BOOST_MULTI_INDEX_MEMBER(
|
||||
car_model,const car_manufacturer * const,manufacturer)
|
||||
member<car_manufacturer,const std::string,&car_manufacturer::name>,
|
||||
member<
|
||||
car_model,const car_manufacturer * const,&car_model::manufacturer>
|
||||
>
|
||||
>
|
||||
>
|
||||
@@ -245,7 +241,7 @@ int main()
|
||||
|
||||
/* find all the cars for the manufacturer given */
|
||||
|
||||
index_iterator<car_table,manufacturer>::type ic0,ic1;
|
||||
boost::multi_index::index<car_table,manufacturer>::type::iterator ic0,ic1;
|
||||
boost::tuples::tie(ic0,ic1)=get<manufacturer>(ct).equal_range(cm);
|
||||
|
||||
/* construct a view (indexed by price) with these */
|
||||
@@ -280,7 +276,7 @@ int main()
|
||||
|
||||
/* find the cars in the range given */
|
||||
|
||||
index_iterator<car_table,price>::type ic0,ic1;
|
||||
boost::multi_index::index<car_table,price>::type::iterator ic0,ic1;
|
||||
ic0=get<price>(ct).lower_bound(min_price);
|
||||
ic1=get<price>(ct).upper_bound(max_price);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of composite keys.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/multi_index/composite_key.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
@@ -56,43 +57,29 @@ struct file_entry
|
||||
* file and size. These indices are firstly ordered by directory, as commands
|
||||
* work on a current directory basis. Composite keys are just fine to model
|
||||
* this.
|
||||
* NB: The use of derivation here instead of simple typedef is explained in
|
||||
* Compiler specifics: type hiding.
|
||||
* NB: The use of derivation here instead of simple typedef helps produce
|
||||
* shorter symbol names in compilation
|
||||
*/
|
||||
|
||||
struct name_key:composite_key<
|
||||
file_entry,
|
||||
BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry*,dir),
|
||||
BOOST_MULTI_INDEX_MEMBER(file_entry,std::string,name)
|
||||
member<file_entry,const file_entry*,&file_entry::dir>,
|
||||
member<file_entry,std::string,&file_entry::name>
|
||||
>{};
|
||||
|
||||
struct size_key:composite_key<
|
||||
file_entry,
|
||||
BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry* const,dir),
|
||||
BOOST_MULTI_INDEX_MEMBER(file_entry,unsigned,size)
|
||||
member<file_entry,const file_entry* const,&file_entry::dir>,
|
||||
member<file_entry,unsigned,&file_entry::size>
|
||||
>{};
|
||||
|
||||
/* see Compiler specifics: composite_key in compilers without partial
|
||||
* template specialization, for info on composite_key_result_less
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
file_entry,
|
||||
indexed_by<
|
||||
/* primary index sorted by name (inside the same directory) */
|
||||
ordered_unique<
|
||||
name_key
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
,composite_key_result_less<name_key::result_type>
|
||||
#endif
|
||||
>,
|
||||
ordered_unique<name_key>,
|
||||
/* secondary index sorted by size (inside the same directory) */
|
||||
ordered_non_unique<
|
||||
size_key
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
,composite_key_result_less<size_key::result_type>
|
||||
#endif
|
||||
>
|
||||
ordered_non_unique<size_key>
|
||||
>
|
||||
> file_system;
|
||||
|
||||
@@ -287,7 +274,7 @@ int main()
|
||||
continue;
|
||||
}
|
||||
|
||||
it->second->execute(++tok.begin(),tok.end());
|
||||
it->second->execute(boost::next(tok.begin()),tok.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of member functions used as key extractors.
|
||||
/* Boost.MultiIndex example of functions used as key extractors.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,6 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/global_fun.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <iostream>
|
||||
@@ -29,8 +30,8 @@ using namespace boost::multi_index;
|
||||
|
||||
struct name_record
|
||||
{
|
||||
name_record(std::string given_name,std::string family_name):
|
||||
given_name(given_name),family_name(family_name)
|
||||
name_record(std::string given_name_,std::string family_name_):
|
||||
given_name(given_name_),family_name(family_name_)
|
||||
{}
|
||||
|
||||
std::string name()const
|
||||
@@ -46,16 +47,23 @@ private:
|
||||
std::string family_name;
|
||||
};
|
||||
|
||||
/* multi_index_container with only one index based on name_record::name().
|
||||
* See Compiler specifics: Use of const_mem_fun_explicit and
|
||||
* mem_fun_explicit for info on BOOST_MULTI_INDEX_CONST_MEM_FUN.
|
||||
std::string::size_type name_record_length(const name_record& r)
|
||||
{
|
||||
return r.name().size();
|
||||
}
|
||||
|
||||
/* multi_index_container with indices based on name_record::name()
|
||||
* and name_record_length().
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
name_record,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
BOOST_MULTI_INDEX_CONST_MEM_FUN(name_record,std::string,name)
|
||||
const_mem_fun<name_record,std::string,&name_record::name>
|
||||
>,
|
||||
ordered_non_unique<
|
||||
global_fun<const name_record&,std::string::size_type,name_record_length>
|
||||
>
|
||||
>
|
||||
> name_record_set;
|
||||
@@ -71,9 +79,20 @@ int main()
|
||||
|
||||
/* list the names in ns in phonebook order */
|
||||
|
||||
std::cout<<"Phonenook order\n"
|
||||
<<"---------------"<<std::endl;
|
||||
for(name_record_set::iterator it=ns.begin();it!=ns.end();++it){
|
||||
std::cout<<it->name()<<std::endl;
|
||||
}
|
||||
|
||||
/* list the names in ns according to their length*/
|
||||
|
||||
std::cout<<"\nLength order\n"
|
||||
<< "------------"<<std::endl;
|
||||
for(nth_index<name_record_set,1>::type::iterator it1=get<1>(ns).begin();
|
||||
it1!=get<1>(ns).end();++it1){
|
||||
std::cout<<it1->name()<<std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of use of hashed indices.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -37,19 +37,15 @@ struct word_counter_entry
|
||||
word_counter_entry(std::string word_):word(word_),occurrences(0){}
|
||||
};
|
||||
|
||||
/* see Compiler specifics: Use of member_offset for info on
|
||||
* BOOST_MULTI_INDEX_MEMBER
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
word_counter_entry,
|
||||
indexed_by<
|
||||
ordered_non_unique<
|
||||
BOOST_MULTI_INDEX_MEMBER(word_counter_entry,unsigned int,occurrences),
|
||||
member<word_counter_entry,unsigned int,&word_counter_entry::occurrences>,
|
||||
std::greater<unsigned int> /* sorted beginning with most frequent */
|
||||
>,
|
||||
hashed_unique<
|
||||
BOOST_MULTI_INDEX_MEMBER(word_counter_entry,std::string,word)
|
||||
member<word_counter_entry,std::string,&word_counter_entry::word>
|
||||
>
|
||||
>
|
||||
> word_counter;
|
||||
@@ -66,25 +62,27 @@ typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
|
||||
|
||||
int main()
|
||||
{
|
||||
/* boostinspect:noascii */
|
||||
|
||||
std::string text=
|
||||
"En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha "
|
||||
"mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga "
|
||||
"antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que "
|
||||
"carnero, salpicón las más noches, duelos y quebrantos los sábados, "
|
||||
"lantejas los viernes, algún palomino de añadidura los domingos, "
|
||||
"consumían las tres partes de su hacienda. El resto della concluían sayo "
|
||||
"mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga "
|
||||
"antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que "
|
||||
"carnero, salpicón las más noches, duelos y quebrantos los sábados, "
|
||||
"lantejas los viernes, algún palomino de añadidura los domingos, "
|
||||
"consumían las tres partes de su hacienda. El resto della concluían sayo "
|
||||
"de velarte, calzas de velludo para las fiestas, con sus pantuflos de lo "
|
||||
"mesmo, y los días de entresemana se honraba con su vellorí de lo más "
|
||||
"fino. Tenía en su casa una ama que pasaba de los cuarenta, y una "
|
||||
"mesmo, y los días de entresemana se honraba con su vellorí de lo más "
|
||||
"fino. Tenía en su casa una ama que pasaba de los cuarenta, y una "
|
||||
"sobrina que no llegaba a los veinte, y un mozo de campo y plaza, que "
|
||||
"así ensillaba el rocín como tomaba la podadera. Frisaba la edad de "
|
||||
"nuestro hidalgo con los cincuenta años; era de complexión recia, seco "
|
||||
"así ensillaba el rocín como tomaba la podadera. Frisaba la edad de "
|
||||
"nuestro hidalgo con los cincuenta años; era de complexión recia, seco "
|
||||
"de carnes, enjuto de rostro, gran madrugador y amigo de la caza. "
|
||||
"Quieren decir que tenía el sobrenombre de Quijada, o Quesada, que en "
|
||||
"Quieren decir que tenía el sobrenombre de Quijada, o Quesada, que en "
|
||||
"esto hay alguna diferencia en los autores que deste caso escriben; "
|
||||
"aunque, por conjeturas verosímiles, se deja entender que se llamaba "
|
||||
"aunque, por conjeturas verosímiles, se deja entender que se llamaba "
|
||||
"Quejana. Pero esto importa poco a nuestro cuento; basta que en la "
|
||||
"narración dél no se salga un punto de la verdad.";
|
||||
"narración dél no se salga un punto de la verdad.";
|
||||
|
||||
/* feed the text into the container */
|
||||
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/* Boost.MultiIndex example of use of Boost.Interprocess allocators.
|
||||
*
|
||||
* Copyright 2003-2026 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/interprocess/allocators/allocator.hpp>
|
||||
#include <boost/interprocess/containers/string.hpp>
|
||||
#include <boost/interprocess/managed_mapped_file.hpp>
|
||||
#include <boost/interprocess/sync/named_mutex.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
namespace bip=boost::interprocess;
|
||||
|
||||
/* shared_string is a string type placeable in shared memory,
|
||||
* courtesy of Boost.Interprocess.
|
||||
*/
|
||||
|
||||
typedef bip::basic_string<
|
||||
char,std::char_traits<char>,
|
||||
bip::allocator<char,bip::managed_mapped_file::segment_manager>
|
||||
> shared_string;
|
||||
|
||||
/* Book record. All its members can be placed in shared memory,
|
||||
* hence the structure itself can too.
|
||||
*/
|
||||
|
||||
struct book
|
||||
{
|
||||
shared_string name;
|
||||
shared_string author;
|
||||
unsigned pages;
|
||||
unsigned prize;
|
||||
|
||||
book(const shared_string::allocator_type& al):
|
||||
name(al),author(al),pages(0),prize(0)
|
||||
{}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,const book& b)
|
||||
{
|
||||
os<<b.author<<": \""<<b.name<<"\", $"<<b.prize<<", "<<b.pages<<" pages\n";
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/* partial_str_less allows for partial searches taking into account
|
||||
* only the first n chars of the strings compared against. See
|
||||
* Tutorial: Basics: Special lookup operations for more info on this
|
||||
* type of comparison functors.
|
||||
*/
|
||||
|
||||
/* partial_string is a mere string holder used to differentiate from
|
||||
* a plain string.
|
||||
*/
|
||||
|
||||
struct partial_string
|
||||
{
|
||||
partial_string(const shared_string& str):str(str){}
|
||||
shared_string str;
|
||||
};
|
||||
|
||||
struct partial_str_less
|
||||
{
|
||||
bool operator()(const shared_string& x,const shared_string& y)const
|
||||
{
|
||||
return x<y;
|
||||
}
|
||||
|
||||
bool operator()(const shared_string& x,const partial_string& y)const
|
||||
{
|
||||
return x.substr(0,y.str.size())<y.str;
|
||||
}
|
||||
|
||||
bool operator()(const partial_string& x,const shared_string& y)const
|
||||
{
|
||||
return x.str<y.substr(0,x.str.size());
|
||||
}
|
||||
};
|
||||
|
||||
/* Define a multi_index_container of book records with indices on
|
||||
* author, name and prize. The index on names allows for partial
|
||||
* searches. This container can be placed in shared memory because:
|
||||
* * book can be placed in shared memory.
|
||||
* * We are using a Boost.Interprocess specific allocator.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
book,
|
||||
indexed_by<
|
||||
ordered_non_unique<
|
||||
member<book,shared_string,&book::author>
|
||||
>,
|
||||
ordered_non_unique<
|
||||
member<book,shared_string,&book::name>,
|
||||
partial_str_less
|
||||
>,
|
||||
ordered_non_unique<
|
||||
member<book,unsigned,&book::prize>
|
||||
>
|
||||
>,
|
||||
bip::allocator<book,bip::managed_mapped_file::segment_manager>
|
||||
> book_container;
|
||||
|
||||
/* A small utility to get data entered via std::cin */
|
||||
|
||||
template<typename T>
|
||||
void enter(const char* msg,T& t)
|
||||
{
|
||||
std::cout<<msg;
|
||||
std::string str;
|
||||
std::getline(std::cin,str);
|
||||
std::istringstream iss(str);
|
||||
iss>>t;
|
||||
}
|
||||
|
||||
void enter(const char* msg,std::string& str)
|
||||
{
|
||||
std::cout<<msg;
|
||||
std::getline(std::cin,str);
|
||||
}
|
||||
|
||||
void enter(const char* msg,shared_string& str)
|
||||
{
|
||||
std::cout<<msg;
|
||||
std::string stdstr;
|
||||
std::getline(std::cin,stdstr);
|
||||
str=stdstr.c_str();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
/* Create (or open) the memory mapped file where the book container
|
||||
* is stored, along with a mutex for synchronized access.
|
||||
*/
|
||||
|
||||
bip::managed_mapped_file seg(
|
||||
bip::open_or_create,"./book_container.db",
|
||||
65536);
|
||||
bip::named_mutex mutex(
|
||||
bip::open_or_create,"7FD6D7E8-320B-11DC-82CF-F0B655D89593");
|
||||
|
||||
/* create or open the book container in shared memory */
|
||||
|
||||
book_container* pbc=seg.find_or_construct<book_container>("book container")(
|
||||
book_container::ctor_args_list(),
|
||||
book_container::allocator_type(seg.get_segment_manager()));
|
||||
|
||||
std::string command_info=
|
||||
"1. list books by author\n"
|
||||
"2. list all books by prize\n"
|
||||
"3. insert a book\n"
|
||||
"4. delete a book\n"
|
||||
"0. exit\n";
|
||||
|
||||
std::cout<<command_info;
|
||||
|
||||
/* main loop */
|
||||
|
||||
for(bool exit=false;!exit;){
|
||||
int command=-1;
|
||||
enter("command: ",command);
|
||||
|
||||
switch(command){
|
||||
case 0:{ /* exit */
|
||||
exit=true;
|
||||
break;
|
||||
}
|
||||
case 1:{ /* list books by author */
|
||||
std::string author;
|
||||
enter("author (empty=all authors): ",author);
|
||||
|
||||
/* operations with the container must be mutex protected */
|
||||
|
||||
bip::scoped_lock<bip::named_mutex> lock(mutex);
|
||||
|
||||
std::pair<book_container::iterator,book_container::iterator> rng;
|
||||
if(author.empty()){
|
||||
rng=std::make_pair(pbc->begin(),pbc->end());
|
||||
}
|
||||
else{
|
||||
rng=pbc->equal_range(
|
||||
shared_string(
|
||||
author.c_str(),
|
||||
shared_string::allocator_type(seg.get_segment_manager())));
|
||||
}
|
||||
|
||||
if(rng.first==rng.second){
|
||||
std::cout<<"no entries\n";
|
||||
}
|
||||
else{
|
||||
std::copy(
|
||||
rng.first,rng.second,std::ostream_iterator<book>(std::cout));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:{ /* list all books by prize */
|
||||
bip::scoped_lock<bip::named_mutex> lock(mutex);
|
||||
|
||||
std::copy(
|
||||
get<2>(*pbc).begin(),get<2>(*pbc).end(),
|
||||
std::ostream_iterator<book>(std::cout));
|
||||
break;
|
||||
}
|
||||
case 3:{ /* insert a book */
|
||||
book b(shared_string::allocator_type(seg.get_segment_manager()));
|
||||
|
||||
enter("author: ",b.author);
|
||||
enter("name: " ,b.name);
|
||||
enter("prize: " ,b.prize);
|
||||
enter("pages: " ,b.pages);
|
||||
|
||||
std::cout<<"insert the following?\n"<<b<<"(y/n): ";
|
||||
char yn='n';
|
||||
enter("",yn);
|
||||
if(yn=='y'||yn=='Y'){
|
||||
bip::scoped_lock<bip::named_mutex> lock(mutex);
|
||||
pbc->insert(b);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 4:{ /* delete a book */
|
||||
shared_string name(
|
||||
shared_string::allocator_type(seg.get_segment_manager()));
|
||||
enter(
|
||||
"name of the book (you can enter\nonly the first few characters): ",
|
||||
name);
|
||||
|
||||
typedef nth_index<book_container,1>::type index_by_name;
|
||||
index_by_name& idx=get<1>(*pbc);
|
||||
index_by_name::iterator it;
|
||||
book b(shared_string::allocator_type(seg.get_segment_manager()));
|
||||
|
||||
{
|
||||
/* Look for a book whose title begins with name. Note that we
|
||||
* are unlocking after doing the search so as to not leave the
|
||||
* container blocked during user prompting. That is also why a
|
||||
* local copy of the book is done.
|
||||
*/
|
||||
|
||||
bip::scoped_lock<bip::named_mutex> lock(mutex);
|
||||
|
||||
it=idx.find(partial_string(name));
|
||||
if(it==idx.end()){
|
||||
std::cout<<"no such book found\n";
|
||||
break;
|
||||
}
|
||||
b=*it;
|
||||
}
|
||||
|
||||
std::cout<<"delete the following?\n"<<b<<"(y/n): ";
|
||||
char yn='n';
|
||||
enter("",yn);
|
||||
if(yn=='y'||yn=='Y'){
|
||||
bip::scoped_lock<bip::named_mutex> lock(mutex);
|
||||
idx.erase(it);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
std::cout<<"select one option:\n"<<command_info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of use of multi_index_container::ctor_args_list.
|
||||
*
|
||||
* Copyright 2003-2004 Joaqu匤 M L�ez Mu�z.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/* Boost.MultiIndex example of use of random access indices.
|
||||
*
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/random_access_index.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* text_container holds words as inserted and also keep them indexed
|
||||
* by dictionary order.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
std::string,
|
||||
indexed_by<
|
||||
random_access<>,
|
||||
ordered_non_unique<identity<std::string> >
|
||||
>
|
||||
> text_container;
|
||||
|
||||
/* ordered index */
|
||||
|
||||
typedef nth_index<text_container,1>::type ordered_text;
|
||||
|
||||
/* Helper function for obtaining the position of an element in the
|
||||
* container.
|
||||
*/
|
||||
|
||||
template<typename IndexIterator>
|
||||
text_container::size_type text_position(
|
||||
const text_container& tc,IndexIterator it)
|
||||
{
|
||||
/* project to the base index and calculate offset from begin() */
|
||||
|
||||
return project<0>(tc,it)-tc.begin();
|
||||
}
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string text=
|
||||
"'Oh, you wicked little thing!' cried Alice, catching up the kitten, "
|
||||
"and giving it a little kiss to make it understand that it was in "
|
||||
"disgrace. 'Really, Dinah ought to have taught you better manners! You "
|
||||
"ought, Dinah, you know you ought!' she added, looking reproachfully at "
|
||||
"the old cat, and speaking in as cross a voice as she could manage "
|
||||
"-- and then she scrambled back into the armchair, taking the kitten and "
|
||||
"the worsted with her, and began winding up the ball again. But she "
|
||||
"didn't get on very fast, as she was talking all the time, sometimes to "
|
||||
"the kitten, and sometimes to herself. Kitty sat very demurely on her "
|
||||
"knee, pretending to watch the progress of the winding, and now and then "
|
||||
"putting out one paw and gently touching the ball, as if it would be glad "
|
||||
"to help, if it might.";
|
||||
|
||||
/* feed the text into the container */
|
||||
|
||||
text_container tc;
|
||||
tc.reserve(text.size()); /* makes insertion faster */
|
||||
text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
|
||||
std::copy(tok.begin(),tok.end(),std::back_inserter(tc));
|
||||
|
||||
std::cout<<"enter a position (0-"<<tc.size()-1<<"):";
|
||||
text_container::size_type pos=tc.size();
|
||||
std::cin>>pos;
|
||||
if(pos>=tc.size()){
|
||||
std::cout<<"out of bounds"<<std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout<<"the word \""<<tc[pos]<<"\" appears at position(s): ";
|
||||
|
||||
std::pair<ordered_text::iterator,ordered_text::iterator> p=
|
||||
get<1>(tc).equal_range(tc[pos]);
|
||||
while(p.first!=p.second){
|
||||
std::cout<<text_position(tc,p.first++)<<" ";
|
||||
}
|
||||
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/* Boost.MultiIndex example of use of rearrange facilities.
|
||||
*
|
||||
* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/random_access_index.hpp>
|
||||
#include <boost/random/binomial_distribution.hpp>
|
||||
#include <boost/random/uniform_real.hpp>
|
||||
#include <boost/random/mersenne_twister.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* We model a card deck with a random access array containing
|
||||
* card numbers (from 0 to 51), supplemented with an additional
|
||||
* index which retains the start ordering.
|
||||
*/
|
||||
|
||||
class deck
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t,num_cards=52);
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
random_access<>, /* base index */
|
||||
random_access<> /* "start" index */
|
||||
>
|
||||
> container_type;
|
||||
container_type cont;
|
||||
|
||||
public:
|
||||
deck()
|
||||
{
|
||||
cont.reserve(num_cards);
|
||||
get<1>(cont).reserve(num_cards);
|
||||
for(std::size_t i=0;i<num_cards;++i)cont.push_back(i);
|
||||
}
|
||||
|
||||
typedef container_type::iterator iterator;
|
||||
typedef container_type::size_type size_type;
|
||||
|
||||
iterator begin()const{return cont.begin();}
|
||||
iterator end()const{return cont.end();}
|
||||
size_type size()const{return cont.size();}
|
||||
|
||||
template<typename InputIterator>
|
||||
void rearrange(InputIterator it)
|
||||
{
|
||||
cont.rearrange(it);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
/* simply rearrange the base index like the start index */
|
||||
|
||||
cont.rearrange(get<1>(cont).begin());
|
||||
}
|
||||
|
||||
std::size_t position(int i)const
|
||||
{
|
||||
/* The position of a card in the deck is calculated by locating
|
||||
* the card through the start index (which is ordered), projecting
|
||||
* to the base index and diffing with the begin position.
|
||||
* Resulting complexity: constant.
|
||||
*/
|
||||
|
||||
return project<0>(cont,get<1>(cont).begin()+i)-cont.begin();
|
||||
}
|
||||
|
||||
std::size_t rising_sequences()const
|
||||
{
|
||||
/* Iterate through all cards and increment the sequence count
|
||||
* when the current position is left to the previous.
|
||||
* Resulting complexity: O(n), n=num_cards.
|
||||
*/
|
||||
|
||||
std::size_t s=1;
|
||||
std::size_t last_pos=0;
|
||||
|
||||
for(std::size_t i=0;i<num_cards;++i){
|
||||
std::size_t pos=position(i);
|
||||
if(pos<last_pos)++s;
|
||||
last_pos=pos;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
/* A vector of reference_wrappers to deck elements can be used
|
||||
* as a view to the deck container.
|
||||
* We use a special implicit_reference_wrapper having implicit
|
||||
* ctor from its base type, as this simplifies the use of generic
|
||||
* techniques on the resulting data structures.
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
class implicit_reference_wrapper:public boost::reference_wrapper<T>
|
||||
{
|
||||
private:
|
||||
typedef boost::reference_wrapper<T> super;
|
||||
public:
|
||||
implicit_reference_wrapper(T& t):super(t){}
|
||||
};
|
||||
|
||||
typedef std::vector<implicit_reference_wrapper<const int> > deck_view;
|
||||
|
||||
/* Riffle shuffle is modeled like this: A cut is selected in the deck
|
||||
* following a binomial distribution. Then, cards are randomly selected
|
||||
* from one packet or the other with probability proportional to
|
||||
* packet size.
|
||||
*/
|
||||
|
||||
template<typename RandomAccessIterator,typename OutputIterator>
|
||||
void riffle_shuffle(
|
||||
RandomAccessIterator first,RandomAccessIterator last,
|
||||
OutputIterator out)
|
||||
{
|
||||
static boost::mt19937 rnd_gen;
|
||||
|
||||
typedef typename std::iterator_traits<
|
||||
RandomAccessIterator>::difference_type difference_type;
|
||||
typedef boost::binomial_distribution<
|
||||
difference_type> rnd_cut_select_type;
|
||||
typedef boost::uniform_real<> rnd_deck_select_type;
|
||||
|
||||
rnd_cut_select_type cut_select(last-first);
|
||||
RandomAccessIterator middle=first+cut_select(rnd_gen);
|
||||
difference_type s0=middle-first;
|
||||
difference_type s1=last-middle;
|
||||
rnd_deck_select_type deck_select;
|
||||
|
||||
while(s0!=0&&s1!=0){
|
||||
if(deck_select(rnd_gen)<(double)s0/(s0+s1)){
|
||||
*out++=*first++;
|
||||
--s0;
|
||||
}
|
||||
else{
|
||||
*out++=*middle++;
|
||||
--s1;
|
||||
}
|
||||
}
|
||||
std::copy(first,first+s0,out);
|
||||
std::copy(middle,middle+s1,out);
|
||||
}
|
||||
|
||||
struct riffle_shuffler
|
||||
{
|
||||
void operator()(deck& d)const
|
||||
{
|
||||
dv.clear();
|
||||
dv.reserve(d.size());
|
||||
riffle_shuffle(
|
||||
d.begin(),d.end(),std::back_inserter(dv)); /* do the shuffling */
|
||||
d.rearrange(dv.begin()); /* apply to the deck */
|
||||
}
|
||||
|
||||
private:
|
||||
mutable deck_view dv;
|
||||
};
|
||||
|
||||
/* A truly random shuffle (up to stdlib implementation quality) using
|
||||
* std::shuffle.
|
||||
*/
|
||||
|
||||
struct random_shuffler
|
||||
{
|
||||
void operator()(deck& d)
|
||||
{
|
||||
dv.clear();
|
||||
dv.reserve(d.size());
|
||||
std::copy(d.begin(),d.end(),std::back_inserter(dv));
|
||||
shuffle_view();
|
||||
d.rearrange(dv.begin()); /* apply to the deck */
|
||||
}
|
||||
|
||||
private:
|
||||
deck_view dv;
|
||||
std::mt19937 e;
|
||||
|
||||
void shuffle_view()
|
||||
{
|
||||
std::shuffle(dv.begin(),dv.end(),e);
|
||||
}
|
||||
};
|
||||
|
||||
/* Repeat a given shuffling algorithm repeats_num times
|
||||
* and obtain the resulting rising sequences number. Average
|
||||
* for tests_num trials.
|
||||
*/
|
||||
|
||||
template<typename Shuffler>
|
||||
double shuffle_test(
|
||||
unsigned int repeats_num,unsigned int tests_num
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Shuffler))
|
||||
{
|
||||
deck d;
|
||||
Shuffler sh;
|
||||
unsigned long total=0;
|
||||
|
||||
for(unsigned int n=0;n<tests_num;++n){
|
||||
for(unsigned m=0;m<repeats_num;++m)sh(d);
|
||||
total+=d.rising_sequences();
|
||||
d.reset();
|
||||
}
|
||||
|
||||
return (double)total/tests_num;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned rifs_num=0;
|
||||
unsigned tests_num=0;
|
||||
|
||||
std::cout<<"number of riffle shuffles (vg 5):";
|
||||
std::cin>>rifs_num;
|
||||
std::cout<<"number of tests (vg 1000):";
|
||||
std::cin>>tests_num;
|
||||
|
||||
std::cout<<"shuffling..."<<std::endl;
|
||||
|
||||
std::cout<<"riffle shuffling\n"
|
||||
" avg number of rising sequences: "
|
||||
<<shuffle_test<riffle_shuffler>(rifs_num,tests_num)
|
||||
<<std::endl;
|
||||
|
||||
std::cout<<"random shuffling\n"
|
||||
" avg number of rising sequences: "
|
||||
<<shuffle_test<random_shuffler>(1,tests_num)
|
||||
<<std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of use of sequenced indices.
|
||||
*
|
||||
* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of serialization of a MRU list.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
typedef Item item_type;
|
||||
typedef typename item_list::iterator iterator;
|
||||
|
||||
mru_list(std::size_t max_num_items):max_num_items(max_num_items){}
|
||||
mru_list(std::size_t max_num_items_):max_num_items(max_num_items_){}
|
||||
|
||||
void insert(const item_type& item)
|
||||
{
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
/* In those compilers that do not accept the member template friend syntax,
|
||||
* some protected and private sections might need to be specified as
|
||||
* public.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS public
|
||||
#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS public
|
||||
#else
|
||||
#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS protected
|
||||
#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS private
|
||||
#endif
|
||||
|
||||
/* GCC does not correctly support in-class using declarations for template
|
||||
* functions. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9810
|
||||
* MSVC 7.1/8.0 seem to have a similar problem, though the conditions in
|
||||
* which the error happens are not that simple. I have yet to isolate this
|
||||
* into a snippet suitable for bug reporting.
|
||||
*/
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, <3)||\
|
||||
BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\
|
||||
BOOST_WORKAROUND(BOOST_MSVC,==1310)||\
|
||||
BOOST_WORKAROUND(BOOST_MSVC,==1400)
|
||||
#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS public
|
||||
#else
|
||||
#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS private
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename T>
|
||||
void adl_swap(T& x,T& y)
|
||||
{
|
||||
using std::swap;
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_ANY_CONTAINER_VIEW_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_ANY_CONTAINER_VIEW_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* type-erased, non-owning view over a ConstIterator-container's range */
|
||||
|
||||
template<typename ConstIterator>
|
||||
class any_container_view
|
||||
{
|
||||
public:
|
||||
template<typename Container>
|
||||
any_container_view(const Container& x):px(&x),pt(vtable_for<Container>()){}
|
||||
|
||||
const void* container()const{return px;}
|
||||
ConstIterator begin()const{return pt->begin(px);}
|
||||
ConstIterator end()const{return pt->end(px);}
|
||||
|
||||
private:
|
||||
struct vtable
|
||||
{
|
||||
ConstIterator (*begin)(const void*);
|
||||
ConstIterator (*end)(const void*);
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
static ConstIterator begin_for(const void* px)
|
||||
{
|
||||
return static_cast<const Container*>(px)->begin();
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
static ConstIterator end_for(const void* px)
|
||||
{
|
||||
return static_cast<const Container*>(px)->end();
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
vtable* vtable_for()
|
||||
{
|
||||
static vtable v=
|
||||
{
|
||||
&begin_for<Container>,
|
||||
&end_for<Container>
|
||||
};
|
||||
|
||||
return &v;
|
||||
}
|
||||
|
||||
const void* px;
|
||||
vtable* pt;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,15 +9,16 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -33,7 +34,7 @@ struct archive_constructed:private noncopyable
|
||||
template<class Archive>
|
||||
archive_constructed(Archive& ar,const unsigned int version)
|
||||
{
|
||||
serialization::load_construct_data_adl(ar,&get(),version);
|
||||
core::load_construct_data_adl(ar,&get(),version);
|
||||
BOOST_TRY{
|
||||
ar>>get();
|
||||
}
|
||||
@@ -47,9 +48,9 @@ struct archive_constructed:private noncopyable
|
||||
template<class Archive>
|
||||
archive_constructed(const char* name,Archive& ar,const unsigned int version)
|
||||
{
|
||||
serialization::load_construct_data_adl(ar,&get(),version);
|
||||
core::load_construct_data_adl(ar,&get(),version);
|
||||
BOOST_TRY{
|
||||
ar>>serialization::make_nvp(name,get());
|
||||
ar>>core::make_nvp(name,get());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
(&get())->~T();
|
||||
@@ -63,10 +64,14 @@ struct archive_constructed:private noncopyable
|
||||
(&get())->~T();
|
||||
}
|
||||
|
||||
T& get(){return *static_cast<T*>(space.address());}
|
||||
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
|
||||
|
||||
T& get(){return *reinterpret_cast<T*>(&space);}
|
||||
|
||||
#include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
|
||||
|
||||
private:
|
||||
aligned_storage<sizeof(T)> space;
|
||||
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_AUGMENTED_STDTUPLE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_AUGMENTED_STDTUPLE_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* augmented_stdtuple<Ts...> derives from std::tuple<Ts...> and provides the
|
||||
* following non-standard constructors:
|
||||
*
|
||||
* - augmented_stdtuple(const Ts& = Ts()...) (this signature is not legal C++,
|
||||
* shown for explanatory purposes).
|
||||
* - augmented_stdtuple(boost::tuple<Ts...>) if sizeof...(Ts) does not exceed
|
||||
* the maximum length of a boost::tuple (10 as of this writing).
|
||||
*/
|
||||
|
||||
template<typename T,typename U>
|
||||
using is_convertible_to_cref=std::is_convertible<T,const U&>;
|
||||
|
||||
template<typename FromList,typename ToList,typename=void>
|
||||
struct are_convertible_to_crefs:mp11::mp_false{};
|
||||
|
||||
template<typename FromList,typename ToList>
|
||||
struct are_convertible_to_crefs<
|
||||
FromList,ToList,
|
||||
typename std::enable_if<
|
||||
(mp11::mp_size<FromList>::value<=mp11::mp_size<ToList>::value)
|
||||
>::type
|
||||
>:
|
||||
mp11::mp_apply<
|
||||
mp11::mp_and,
|
||||
mp11::mp_transform<
|
||||
is_convertible_to_cref,
|
||||
FromList,
|
||||
mp11::mp_take_c<ToList,mp11::mp_size<FromList>::value>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename... Ts>
|
||||
struct augmented_stdtuple:std::tuple<Ts...>
|
||||
{
|
||||
private:
|
||||
using super=std::tuple<Ts...>;
|
||||
static constexpr std::size_t N=sizeof...(Ts);
|
||||
|
||||
template<typename... Args>
|
||||
using are_convertible_to_crefs=
|
||||
typename detail::are_convertible_to_crefs<mp11::mp_list<Args...>,super>;
|
||||
|
||||
struct boost_tuple_too_short{};
|
||||
using boost_tuple_arg=mp11::mp_eval_if_c<
|
||||
(mp11::mp_size<boost::tuple<>>::value < N),
|
||||
boost_tuple_too_short,
|
||||
boost::tuple,Ts...
|
||||
>;
|
||||
|
||||
struct full_args_ctor{};
|
||||
augmented_stdtuple(full_args_ctor,const Ts&... args):super(args...){}
|
||||
|
||||
struct partial_args_ctor{};
|
||||
template<std::size_t... Is,typename... Args>
|
||||
augmented_stdtuple(
|
||||
partial_args_ctor,mp11::index_sequence<Is...>,Args&&... args):
|
||||
augmented_stdtuple(
|
||||
full_args_ctor{},
|
||||
std::forward<Args>(args)...,
|
||||
typename std::tuple_element<sizeof...(Args)+Is,super>::type()...)
|
||||
{}
|
||||
|
||||
struct boost_tuple_ctor{};
|
||||
template<std::size_t... Is>
|
||||
augmented_stdtuple(
|
||||
boost_tuple_ctor,mp11::index_sequence<Is...>,const boost_tuple_arg& x):
|
||||
super(tuples::get<Is>(x)...)
|
||||
{}
|
||||
|
||||
public:
|
||||
template<
|
||||
typename... Args,
|
||||
typename std::enable_if<
|
||||
are_convertible_to_crefs<Args&&...>::value
|
||||
>::type* =nullptr
|
||||
>
|
||||
augmented_stdtuple(Args&&... args):
|
||||
augmented_stdtuple(
|
||||
partial_args_ctor(),mp11::make_index_sequence<N-sizeof...(Args)>(),
|
||||
std::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
augmented_stdtuple(const super& x):super(x){}
|
||||
|
||||
augmented_stdtuple(const boost_tuple_arg& x):
|
||||
augmented_stdtuple(
|
||||
boost_tuple_ctor(),mp11::make_index_sequence<N>(),x)
|
||||
{}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,14 +9,16 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/multi_index/detail/adl_swap.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace boost{
|
||||
@@ -38,34 +40,52 @@ namespace detail{
|
||||
* "of zero length", http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14176
|
||||
* C++ Standard Library Defect Report List (Revision 28), issue 199
|
||||
* "What does allocate(0) return?",
|
||||
* http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#199
|
||||
* http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199
|
||||
*/
|
||||
|
||||
template<typename T,typename Allocator=std::allocator<T> >
|
||||
struct auto_space:private noncopyable
|
||||
{
|
||||
explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1):
|
||||
al_(al),n_(n),data_(n_?al_.allocate(n_):0)
|
||||
typedef allocator_rebind_t<Allocator,T> allocator;
|
||||
typedef allocator_pointer_t<allocator> pointer;
|
||||
typedef allocator_size_type_t<allocator> size_type;
|
||||
|
||||
explicit auto_space(const Allocator& al=Allocator(),size_type n=1):
|
||||
al_(al),n_(n),data_(n_?allocator_allocate(al_,n_):pointer(0))
|
||||
{}
|
||||
|
||||
~auto_space()
|
||||
{
|
||||
if(n_)al_.deallocate(data_,n_);
|
||||
}
|
||||
~auto_space(){if(n_)allocator_deallocate(al_,data_,n_);}
|
||||
|
||||
T* data()const{return data_;}
|
||||
Allocator get_allocator()const{return al_;}
|
||||
|
||||
pointer data()const{return data_;}
|
||||
|
||||
void swap(auto_space& x)
|
||||
{
|
||||
swap(
|
||||
x,
|
||||
boost::integral_constant<
|
||||
bool,
|
||||
allocator_propagate_on_container_swap_t<allocator>::value>());
|
||||
}
|
||||
|
||||
void swap(auto_space& x,boost::true_type /* swap_allocators */)
|
||||
{
|
||||
adl_swap(al_,x.al_);
|
||||
std::swap(n_,x.n_);
|
||||
std::swap(data_,x.data_);
|
||||
}
|
||||
|
||||
void swap(auto_space& x,boost::false_type /* swap_allocators */)
|
||||
{
|
||||
std::swap(n_,x.n_);
|
||||
std::swap(data_,x.data_);
|
||||
}
|
||||
|
||||
private:
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,T>::type al_;
|
||||
std::size_t n_;
|
||||
T* data_;
|
||||
allocator al_;
|
||||
size_type n_;
|
||||
pointer data_;
|
||||
};
|
||||
|
||||
template<typename T,typename Allocator>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
struct bad_archive_exception:std::runtime_error
|
||||
{
|
||||
bad_archive_exception():std::runtime_error("Invalid or corrupted archive"){}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,18 +9,16 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/multi_index/detail/index_base.hpp>
|
||||
#include <boost/multi_index/detail/is_index_list.hpp>
|
||||
#include <boost/multi_index/detail/msvc_index_specifier.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost{
|
||||
@@ -29,51 +27,31 @@ namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* MPL machinery to construct a linear hierarchy of indices out of
|
||||
* a index list.
|
||||
/* Mp11 machinery to construct a linear hierarchy of indices out of
|
||||
* an index list.
|
||||
*/
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1310)
|
||||
struct index_applier
|
||||
{
|
||||
template<typename IndexSpecifierMeta,typename SuperMeta>
|
||||
struct apply:
|
||||
msvc_index_specifier<IndexSpecifierMeta::type>::
|
||||
template result_index_class<SuperMeta>
|
||||
{
|
||||
};
|
||||
};
|
||||
#else
|
||||
struct index_applier
|
||||
{
|
||||
template<typename IndexSpecifierMeta,typename Super>
|
||||
struct apply
|
||||
{
|
||||
typedef typename IndexSpecifierMeta::type index_specifier;
|
||||
typedef typename index_specifier::
|
||||
BOOST_NESTED_TEMPLATE index_class<Super>::type type;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
template<typename N,typename Mp11IndexSpecifierList,typename SuperMeta>
|
||||
using nth_layer_index=typename mp11::mp_at<Mp11IndexSpecifierList,N>::
|
||||
template index_class<SuperMeta>::type;
|
||||
|
||||
template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
|
||||
struct nth_layer
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int,length=mpl::size<IndexSpecifierList>::value);
|
||||
|
||||
typedef typename mpl::eval_if_c<
|
||||
N==length,
|
||||
mpl::identity<index_base<Value,IndexSpecifierList,Allocator> >,
|
||||
mpl::apply2<
|
||||
index_applier,
|
||||
mpl::at_c<IndexSpecifierList,N>,
|
||||
nth_layer<N+1,Value,IndexSpecifierList,Allocator>
|
||||
>
|
||||
>::type type;
|
||||
using Mp11IndexSpecifierList=detail::mp11_index_list<IndexSpecifierList>;
|
||||
using type=mp11::mp_eval_if_c<
|
||||
N==mp11::mp_size<Mp11IndexSpecifierList>::value,
|
||||
index_base<Value,IndexSpecifierList,Allocator>,
|
||||
nth_layer_index,
|
||||
mp11::mp_int<N>,
|
||||
Mp11IndexSpecifierList,
|
||||
nth_layer<N+1,Value,IndexSpecifierList,Allocator>
|
||||
>;
|
||||
};
|
||||
|
||||
template<typename Value,typename IndexSpecifierList,typename Allocator>
|
||||
struct multi_index_base_type:nth_layer<0,Value,IndexSpecifierList,Allocator>
|
||||
struct multi_index_base_type:
|
||||
nth_layer<0,Value,IndexSpecifierList,Allocator>
|
||||
{
|
||||
BOOST_STATIC_ASSERT(detail::is_index_list<IndexSpecifierList>::value);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/* Copyright 2003-2026 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/core/serialization.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Iterator class for node-based indices with bidirectional
|
||||
* iterators (ordered and sequenced indices.)
|
||||
*/
|
||||
|
||||
template<typename Node>
|
||||
class bidir_node_iterator:
|
||||
public bidirectional_iterator_helper<
|
||||
bidir_node_iterator<Node>,
|
||||
typename Node::value_type,
|
||||
typename Node::difference_type,
|
||||
const typename Node::value_type*,
|
||||
const typename Node::value_type&>
|
||||
{
|
||||
public:
|
||||
/* coverity[uninit_ctor]: suppress warning */
|
||||
bidir_node_iterator(){}
|
||||
explicit bidir_node_iterator(Node* node_):node(node_){}
|
||||
|
||||
const typename Node::value_type& operator*()const
|
||||
{
|
||||
return node->value();
|
||||
}
|
||||
|
||||
bidir_node_iterator& operator++()
|
||||
{
|
||||
Node::increment(node);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bidir_node_iterator& operator--()
|
||||
{
|
||||
Node::decrement(node);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* Serialization. As for why the following is public,
|
||||
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
|
||||
*/
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,const unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive& ar,const unsigned int)const
|
||||
{
|
||||
node_base_type* bnode=get_node();
|
||||
ar<<core::make_nvp("pointer",bnode);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>core::make_nvp("pointer",bnode);
|
||||
node=typename Node::pointer(static_cast<Node*>(bnode));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* get_node is not to be used by the user */
|
||||
|
||||
typedef Node node_type;
|
||||
|
||||
Node* get_node()const{return raw_ptr<Node*>(node);}
|
||||
|
||||
private:
|
||||
typename Node::pointer node;
|
||||
};
|
||||
|
||||
template<typename Node>
|
||||
bool operator==(
|
||||
const bidir_node_iterator<Node>& x,
|
||||
const bidir_node_iterator<Node>& y)
|
||||
{
|
||||
return x.get_node()==y.get_node();
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,21 +9,26 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/hash_index_node.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/seq/elem.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
#include <cstddef>
|
||||
#include <limits.h>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/multi_index/detail/bad_archive_exception.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#endif
|
||||
|
||||
@@ -35,103 +40,154 @@ namespace detail{
|
||||
|
||||
/* bucket structure for use by hashed indices */
|
||||
|
||||
#define BOOST_MULTI_INDEX_BA_SIZES_32BIT \
|
||||
(53ul)(97ul)(193ul)(389ul)(769ul) \
|
||||
(1543ul)(3079ul)(6151ul)(12289ul)(24593ul) \
|
||||
(49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \
|
||||
(1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \
|
||||
(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
|
||||
(1610612741ul)(3221225473ul)
|
||||
|
||||
#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */
|
||||
#define BOOST_MULTI_INDEX_BA_SIZES \
|
||||
BOOST_MULTI_INDEX_BA_SIZES_32BIT \
|
||||
(4294967291ul)
|
||||
#else
|
||||
/* obtained with aid from
|
||||
* http://javaboutique.internet.com/prime_numb/
|
||||
* http://www.rsok.com/~jrm/next_ten_primes.html
|
||||
* and verified with
|
||||
* http://www.alpertron.com.ar/ECM.HTM
|
||||
*/
|
||||
|
||||
#define BOOST_MULTI_INDEX_BA_SIZES \
|
||||
BOOST_MULTI_INDEX_BA_SIZES_32BIT \
|
||||
(6442450939ul)(12884901893ul)(25769803751ul)(51539607551ul) \
|
||||
(103079215111ul)(206158430209ul)(412316860441ul)(824633720831ul) \
|
||||
(1649267441651ul)(3298534883309ul)(6597069766657ul)(13194139533299ul) \
|
||||
(26388279066623ul)(52776558133303ul)(105553116266489ul)(211106232532969ul) \
|
||||
(422212465066001ul)(844424930131963ul)(1688849860263953ul) \
|
||||
(3377699720527861ul)(6755399441055731ul)(13510798882111483ul) \
|
||||
(27021597764222939ul)(54043195528445957ul)(108086391056891903ul) \
|
||||
(216172782113783843ul)(432345564227567621ul)(864691128455135207ul) \
|
||||
(1729382256910270481ul)(3458764513820540933ul)(6917529027641081903ul) \
|
||||
(13835058055282163729ul)(18446744073709551557ul)
|
||||
#endif
|
||||
|
||||
template<bool _=true> /* templatized to have in-header static var defs */
|
||||
class bucket_array_base:private noncopyable
|
||||
{
|
||||
protected:
|
||||
inline static std::size_t next_prime(std::size_t n)
|
||||
static const std::size_t sizes[
|
||||
BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)];
|
||||
|
||||
static std::size_t size_index(std::size_t n)
|
||||
{
|
||||
static const std::size_t prime_list[]={
|
||||
53ul, 97ul, 193ul, 389ul, 769ul,
|
||||
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
|
||||
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
|
||||
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
|
||||
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
|
||||
1610612741ul, 3221225473ul,
|
||||
|
||||
#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */
|
||||
4294967291ul
|
||||
#else
|
||||
/* obtained with aid from
|
||||
* http://javaboutique.internet.com/prime_numb/
|
||||
* http://www.rsok.com/~jrm/next_ten_primes.html
|
||||
* and verified with
|
||||
* http://www.alpertron.com.ar/ECM.HTM
|
||||
*/
|
||||
|
||||
6442450939ul, 12884901893ul, 25769803751ul, 51539607551ul,
|
||||
103079215111ul, 206158430209ul, 412316860441ul, 824633720831ul,
|
||||
1649267441651ul, 3298534883309ul, 6597069766657ul, 13194139533299ul,
|
||||
26388279066623ul, 52776558133303ul, 105553116266489ul, 211106232532969ul,
|
||||
422212465066001ul, 844424930131963ul, 1688849860263953ul,
|
||||
3377699720527861ul, 6755399441055731ul, 13510798882111483ul,
|
||||
27021597764222939ul, 54043195528445957ul, 108086391056891903ul,
|
||||
216172782113783843ul, 432345564227567621ul, 864691128455135207ul,
|
||||
1729382256910270481ul, 3458764513820540933ul, 6917529027641081903ul,
|
||||
13835058055282163729ul, 18446744073709551557ul
|
||||
#endif
|
||||
|
||||
};
|
||||
static const std::size_t prime_list_size=
|
||||
sizeof(prime_list)/sizeof(prime_list[0]);
|
||||
|
||||
std::size_t const *bound=
|
||||
std::lower_bound(prime_list,prime_list+prime_list_size,n);
|
||||
if(bound==prime_list+prime_list_size)bound--;
|
||||
return *bound;
|
||||
const std::size_t *bound=std::lower_bound(sizes,sizes+sizes_length,n);
|
||||
if(bound==sizes+sizes_length)--bound;
|
||||
return bound-sizes;
|
||||
}
|
||||
|
||||
#define BOOST_MULTI_INDEX_BA_POSITION_CASE(z,n,_) \
|
||||
case n:return hash%BOOST_PP_SEQ_ELEM(n,BOOST_MULTI_INDEX_BA_SIZES);
|
||||
|
||||
static std::size_t position(std::size_t hash,std::size_t size_index_)
|
||||
{
|
||||
/* Accelerate hash%sizes[size_index_] by replacing with a switch on
|
||||
* hash%Ci expressions, each Ci a compile-time constant, which the
|
||||
* compiler can implement without using integer division.
|
||||
*/
|
||||
|
||||
switch(size_index_){
|
||||
default: /* never used */
|
||||
BOOST_PP_REPEAT(
|
||||
BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES),
|
||||
BOOST_MULTI_INDEX_BA_POSITION_CASE,~)
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static const std::size_t sizes_length;
|
||||
};
|
||||
|
||||
template<bool _>
|
||||
const std::size_t bucket_array_base<_>::sizes[]={
|
||||
BOOST_PP_SEQ_ENUM(BOOST_MULTI_INDEX_BA_SIZES)
|
||||
};
|
||||
|
||||
template<bool _>
|
||||
const std::size_t bucket_array_base<_>::sizes_length=
|
||||
sizeof(bucket_array_base<_>::sizes)/
|
||||
sizeof(bucket_array_base<_>::sizes[0]);
|
||||
|
||||
#undef BOOST_MULTI_INDEX_BA_POSITION_CASE
|
||||
#undef BOOST_MULTI_INDEX_BA_SIZES
|
||||
#undef BOOST_MULTI_INDEX_BA_SIZES_32BIT
|
||||
|
||||
template<typename Allocator>
|
||||
class bucket_array:public bucket_array_base
|
||||
class bucket_array:bucket_array_base<>
|
||||
{
|
||||
typedef bucket_array_base<> super;
|
||||
typedef hashed_index_base_node_impl<
|
||||
allocator_rebind_t<
|
||||
Allocator,
|
||||
char
|
||||
>
|
||||
> base_node_impl_type;
|
||||
|
||||
public:
|
||||
bucket_array(const Allocator& al,hashed_index_node_impl* end_,std::size_t size):
|
||||
size_(bucket_array_base::next_prime(size)),
|
||||
spc(al,size_+1)
|
||||
typedef typename base_node_impl_type::base_pointer base_pointer;
|
||||
typedef typename base_node_impl_type::pointer pointer;
|
||||
|
||||
bucket_array(const Allocator& al,pointer end_,std::size_t size_):
|
||||
size_index_(super::size_index(size_)),
|
||||
spc(al,static_cast<auto_space_size_type>(super::sizes[size_index_]+1))
|
||||
{
|
||||
clear();
|
||||
end()->next()=end_;
|
||||
end_->next()=end();
|
||||
clear(end_);
|
||||
}
|
||||
|
||||
std::size_t size()const
|
||||
{
|
||||
return size_;
|
||||
return super::sizes[size_index_];
|
||||
}
|
||||
|
||||
std::size_t position(std::size_t hash)const
|
||||
{
|
||||
return hash%size_;
|
||||
return super::position(hash,size_index_);
|
||||
}
|
||||
|
||||
hashed_index_node_impl* begin()const{return &buckets()[0];}
|
||||
hashed_index_node_impl* end()const{return &buckets()[size_];}
|
||||
hashed_index_node_impl* at(std::size_t n)const{return &buckets()[n];}
|
||||
base_pointer begin()const{return buckets();}
|
||||
base_pointer end()const{return buckets()+size();}
|
||||
base_pointer at(std::size_t n)const{return buckets()+n;}
|
||||
|
||||
std::size_t first_nonempty(std::size_t n)const
|
||||
void clear(pointer end_)
|
||||
{
|
||||
for(;;++n){
|
||||
hashed_index_node_impl* x=at(n);
|
||||
if(x->next()!=x)return n;
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for(hashed_index_node_impl* x=begin(),*y=end();x!=y;++x)x->next()=x;
|
||||
}
|
||||
for(base_pointer x=begin(),y=end();x!=y;++x)x->prior()=pointer(0);
|
||||
end()->prior()=end_->prior()=end_;
|
||||
end_->next()=end();
|
||||
}
|
||||
|
||||
void swap(bucket_array& x)
|
||||
{
|
||||
std::swap(size_,x.size_);
|
||||
std::swap(size_index_,x.size_index_);
|
||||
spc.swap(x.spc);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t size_;
|
||||
auto_space<hashed_index_node_impl,Allocator> spc;
|
||||
template<typename BoolConstant>
|
||||
void swap(bucket_array& x,BoolConstant swap_allocators)
|
||||
{
|
||||
std::swap(size_index_,x.size_index_);
|
||||
spc.swap(x.spc,swap_allocators);
|
||||
}
|
||||
|
||||
hashed_index_node_impl* buckets()const
|
||||
private:
|
||||
typedef auto_space<base_node_impl_type,Allocator> auto_space_type;
|
||||
typedef typename auto_space_type::size_type auto_space_size_type;
|
||||
|
||||
std::size_t size_index_;
|
||||
auto_space_type spc;
|
||||
|
||||
base_pointer buckets()const
|
||||
{
|
||||
return spc.data();
|
||||
}
|
||||
@@ -168,28 +224,19 @@ void swap(bucket_array<Allocator>& x,bucket_array<Allocator>& y)
|
||||
* somehow invalid archive.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
namespace serialization{
|
||||
#else
|
||||
namespace multi_index{
|
||||
namespace detail{
|
||||
#endif
|
||||
|
||||
template<class Archive,typename Allocator>
|
||||
inline void load_construct_data(
|
||||
Archive&,boost::multi_index::detail::bucket_array<Allocator>*,
|
||||
const unsigned int)
|
||||
{
|
||||
throw_exception(
|
||||
archive::archive_exception(archive::archive_exception::other_exception));
|
||||
throw_exception(boost::multi_index::detail::bad_archive_exception());
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
} /* namespace serialization */
|
||||
#else
|
||||
} /* namespace multi_index::detail */
|
||||
} /* namespace multi_index */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <tuple>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* std::tuple wrapper providing the cons-based interface of boost::tuple for
|
||||
* composite_key interoperability.
|
||||
*/
|
||||
|
||||
template<typename StdTuple,std::size_t N>
|
||||
struct cons_stdtuple;
|
||||
|
||||
struct cons_stdtuple_ctor_terminal
|
||||
{
|
||||
typedef boost::tuples::null_type result_type;
|
||||
|
||||
template<typename StdTuple>
|
||||
static result_type create(const StdTuple&)
|
||||
{
|
||||
return boost::tuples::null_type();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename StdTuple,std::size_t N>
|
||||
struct cons_stdtuple_ctor_normal
|
||||
{
|
||||
typedef cons_stdtuple<StdTuple,N> result_type;
|
||||
|
||||
static result_type create(const StdTuple& t)
|
||||
{
|
||||
return result_type(t);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename StdTuple,std::size_t N=0>
|
||||
struct cons_stdtuple_ctor:
|
||||
mp11::mp_if_c<
|
||||
N<std::tuple_size<StdTuple>::value,
|
||||
cons_stdtuple_ctor_normal<StdTuple,N>,
|
||||
cons_stdtuple_ctor_terminal
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename StdTuple,std::size_t N>
|
||||
struct cons_stdtuple
|
||||
{
|
||||
typedef typename std::tuple_element<N,StdTuple>::type head_type;
|
||||
typedef cons_stdtuple_ctor<StdTuple,N+1> tail_ctor;
|
||||
typedef typename tail_ctor::result_type tail_type;
|
||||
|
||||
cons_stdtuple(const StdTuple& t_):t(t_){}
|
||||
|
||||
const head_type& get_head()const{return std::get<N>(t);}
|
||||
tail_type get_tail()const{return tail_ctor::create(t);}
|
||||
|
||||
const StdTuple& t;
|
||||
};
|
||||
|
||||
template<typename StdTuple>
|
||||
typename cons_stdtuple_ctor<StdTuple>::result_type
|
||||
make_cons_stdtuple(const StdTuple& t)
|
||||
{
|
||||
return cons_stdtuple_ctor<StdTuple>::create(t);
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
@@ -31,13 +31,15 @@ struct converter
|
||||
static Index& index(MultiIndexContainer& x){return x;}
|
||||
|
||||
static typename Index::const_iterator const_iterator(
|
||||
const MultiIndexContainer& x,typename MultiIndexContainer::node_type* node)
|
||||
const MultiIndexContainer& x,
|
||||
typename MultiIndexContainer::final_node_type* node)
|
||||
{
|
||||
return x.Index::make_iterator(node);
|
||||
}
|
||||
|
||||
static typename Index::iterator iterator(
|
||||
MultiIndexContainer& x,typename MultiIndexContainer::node_type* node)
|
||||
MultiIndexContainer& x,
|
||||
typename MultiIndexContainer::final_node_type* node)
|
||||
{
|
||||
return x.Index::make_iterator(node);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,17 +9,20 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -53,14 +56,30 @@ struct copy_map_entry
|
||||
}
|
||||
};
|
||||
|
||||
struct copy_map_value_copier
|
||||
{
|
||||
template<typename Value>
|
||||
const Value& operator()(Value& x)const{return x;}
|
||||
};
|
||||
|
||||
struct copy_map_value_mover
|
||||
{
|
||||
template<typename Value>
|
||||
Value&& operator()(Value& x)const{return std::move(x);}
|
||||
};
|
||||
|
||||
template <typename Node,typename Allocator>
|
||||
class copy_map:private noncopyable
|
||||
{
|
||||
typedef allocator_rebind_t<Allocator,Node> allocator_type;
|
||||
typedef allocator_pointer_t<allocator_type> pointer;
|
||||
|
||||
public:
|
||||
typedef const copy_map_entry<Node>* const_iterator;
|
||||
typedef const copy_map_entry<Node>* const_iterator;
|
||||
typedef allocator_size_type_t<allocator_type> size_type;
|
||||
|
||||
copy_map(
|
||||
const Allocator& al,std::size_t size,Node* header_org,Node* header_cpy):
|
||||
const Allocator& al,size_type size,Node* header_org,Node* header_cpy):
|
||||
al_(al),size_(size),spc(al_,size_),n(0),
|
||||
header_org_(header_org),header_cpy_(header_cpy),released(false)
|
||||
{}
|
||||
@@ -68,33 +87,19 @@ public:
|
||||
~copy_map()
|
||||
{
|
||||
if(!released){
|
||||
for(std::size_t i=0;i<n;++i){
|
||||
boost::detail::allocator::destroy(&spc.data()[i].second->value);
|
||||
deallocate(spc.data()[i].second);
|
||||
for(size_type i=0;i<n;++i){
|
||||
allocator_destroy(
|
||||
al_,boost::addressof((spc.data()+i)->second->value()));
|
||||
deallocate((spc.data()+i)->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const_iterator begin()const{return spc.data();}
|
||||
const_iterator end()const{return spc.data()+n;}
|
||||
const_iterator begin()const{return raw_ptr<const_iterator>(spc.data());}
|
||||
const_iterator end()const{return raw_ptr<const_iterator>(spc.data()+n);}
|
||||
|
||||
void clone(Node* node)
|
||||
{
|
||||
spc.data()[n].first=node;
|
||||
spc.data()[n].second=al_.allocate(1);
|
||||
BOOST_TRY{
|
||||
boost::detail::allocator::construct(
|
||||
&spc.data()[n].second->value,node->value);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
deallocate(spc.data()[n].second);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
++n;
|
||||
|
||||
if(n==size_)std::sort(spc.data(),spc.data()+size_);
|
||||
}
|
||||
void copy_clone(Node* node){clone(node,copy_map_value_copier());}
|
||||
void move_clone(Node* node){clone(node,copy_map_value_mover());}
|
||||
|
||||
Node* find(Node* node)const
|
||||
{
|
||||
@@ -109,18 +114,46 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,Node>::type al_;
|
||||
std::size_t size_;
|
||||
auto_space<copy_map_entry<Node>,Allocator> spc;
|
||||
std::size_t n;
|
||||
Node* header_org_;
|
||||
Node* header_cpy_;
|
||||
bool released;
|
||||
allocator_type al_;
|
||||
size_type size_;
|
||||
auto_space<copy_map_entry<Node>,Allocator> spc;
|
||||
size_type n;
|
||||
Node* header_org_;
|
||||
Node* header_cpy_;
|
||||
bool released;
|
||||
|
||||
pointer allocate()
|
||||
{
|
||||
return allocator_allocate(al_,1);
|
||||
}
|
||||
|
||||
void deallocate(Node* node)
|
||||
{
|
||||
al_.deallocate(node,1);
|
||||
allocator_deallocate(al_,static_cast<pointer>(node),1);
|
||||
}
|
||||
|
||||
template<typename ValueAccess>
|
||||
void clone(Node* node,ValueAccess access)
|
||||
{
|
||||
(spc.data()+n)->first=node;
|
||||
(spc.data()+n)->second=raw_ptr<Node*>(allocate());
|
||||
BOOST_TRY{
|
||||
allocator_construct(
|
||||
al_,boost::addressof((spc.data()+n)->second->value()),
|
||||
access(node->value()));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
deallocate((spc.data()+n)->second);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
++n;
|
||||
|
||||
if(n==size_){
|
||||
std::sort(
|
||||
raw_ptr<copy_map_entry<Node>*>(spc.data()),
|
||||
raw_ptr<copy_map_entry<Node>*>(spc.data())+size_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_DEF_CTOR_TUPLE_CONS_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_DEF_CTOR_TUPLE_CONS_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
/* In MSVC, tuples::cons is not default constructible. We provide a
|
||||
* tiny wrapper around tuple::cons filling that hole.
|
||||
*/
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename Cons>
|
||||
struct default_constructible_tuple_cons:Cons
|
||||
{
|
||||
default_constructible_tuple_cons():
|
||||
Cons(
|
||||
Cons::head_type(),
|
||||
static_cast<const Cons::tail_type&>(
|
||||
default_constructible_tuple_cons<Cons::tail_type>()))
|
||||
{}
|
||||
|
||||
default_constructible_tuple_cons(const Cons& cons):Cons(cons){}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct default_constructible_tuple_cons<tuples::null_type>:tuples::null_type
|
||||
{
|
||||
default_constructible_tuple_cons(){}
|
||||
default_constructible_tuple_cons(const tuples::null_type&){}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif /* BOOST_MSVC */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#if !defined(BOOST_CONFIG_HPP)
|
||||
#error <boost/config.hpp> must be included before this header
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DETAIL_UNDEF_IF_CONSTEXPR_MACRO)
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR)
|
||||
#define BOOST_MULTI_INDEX_IF_CONSTEXPR if constexpr
|
||||
#else
|
||||
#define BOOST_MULTI_INDEX_IF_CONSTEXPR if
|
||||
#if defined(BOOST_MSVC)
|
||||
#define BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) /* conditional expression is constant */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#undef BOOST_MULTI_INDEX_IF_CONSTEXPR
|
||||
#if defined(BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED)
|
||||
#pragma warning(pop)
|
||||
#undef BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Used to mark a special ctor variant that copies the internal objects of
|
||||
* a container but not its elements.
|
||||
*/
|
||||
|
||||
struct do_not_copy_elements_tag{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,12 +9,11 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost{
|
||||
@@ -32,30 +31,30 @@ class duplicates_iterator
|
||||
{
|
||||
public:
|
||||
typedef typename Node::value_type value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename Node::difference_type difference_type;
|
||||
typedef const typename Node::value_type* pointer;
|
||||
typedef const typename Node::value_type& reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
duplicates_iterator(Node* node,Node* end,Predicate pred):
|
||||
node(node),begin_chunk(0),end(end),pred(pred)
|
||||
duplicates_iterator(Node* node_,Node* end_,Predicate pred_):
|
||||
node(node_),begin_chunk(0),end(end_),pred(pred_)
|
||||
{
|
||||
advance();
|
||||
}
|
||||
|
||||
duplicates_iterator(Node* end,Predicate pred):
|
||||
node(end),begin_chunk(end),end(end),pred(pred)
|
||||
duplicates_iterator(Node* end_,Predicate pred_):
|
||||
node(end_),begin_chunk(end_),end(end_),pred(pred_)
|
||||
{
|
||||
}
|
||||
|
||||
reference operator*()const
|
||||
{
|
||||
return node->value;
|
||||
return node->value();
|
||||
}
|
||||
|
||||
pointer operator->()const
|
||||
{
|
||||
return node->value;
|
||||
return &node->value();
|
||||
}
|
||||
|
||||
duplicates_iterator& operator++()
|
||||
@@ -77,15 +76,14 @@ public:
|
||||
private:
|
||||
void sync()
|
||||
{
|
||||
if(pred(begin_chunk->value,node->value))advance();
|
||||
if(node!=end&&pred(begin_chunk->value(),node->value()))advance();
|
||||
}
|
||||
|
||||
void advance()
|
||||
{
|
||||
for(Node* node2=node;node!=end;node=node2){
|
||||
Node::increment(node2);
|
||||
if(node2!=end&&!pred(node->value,node2->value))break;
|
||||
node=node2;
|
||||
if(node2!=end&&!pred(node->value(),node2->value()))break;
|
||||
}
|
||||
begin_chunk=node;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,12 +9,12 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -28,9 +28,7 @@ template<typename Tag>
|
||||
struct has_tag
|
||||
{
|
||||
template<typename Index>
|
||||
struct apply:mpl::contains<BOOST_DEDUCED_TYPENAME Index::tag_list,Tag>
|
||||
{
|
||||
};
|
||||
using fn=mp11::mp_contains<typename Index::tag_list,Tag>;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
@@ -39,4 +37,4 @@ struct has_tag
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,25 +9,21 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
#include <boost/mpl/aux_/na.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
|
||||
template<class T> struct hash; /* fwd decl. */
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
@@ -48,54 +44,44 @@ namespace detail{
|
||||
* argument-dependent polymorphism.
|
||||
*/
|
||||
|
||||
template<typename KeyFromValue>
|
||||
struct index_args_default_hash
|
||||
{
|
||||
typedef ::boost::hash<typename KeyFromValue::result_type> type;
|
||||
};
|
||||
|
||||
template<typename KeyFromValue>
|
||||
struct index_args_default_pred
|
||||
{
|
||||
typedef std::equal_to<typename KeyFromValue::result_type> type;
|
||||
};
|
||||
|
||||
template<typename Arg1,typename Arg2,typename Arg3,typename Arg4>
|
||||
struct hashed_index_args
|
||||
{
|
||||
typedef is_tag<Arg1> full_form;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
typedef mp11::mp_if<
|
||||
full_form,
|
||||
Arg1,
|
||||
tag< > >::type tag_list_type;
|
||||
typedef typename mpl::if_<
|
||||
tag< > > tag_list_type;
|
||||
typedef mp11::mp_if<
|
||||
full_form,
|
||||
Arg2,
|
||||
Arg1>::type key_from_value_type;
|
||||
typedef typename mpl::if_<
|
||||
Arg1> key_from_value_type;
|
||||
typedef mp11::mp_if<
|
||||
full_form,
|
||||
Arg3,
|
||||
Arg2>::type supplied_hash_type;
|
||||
typedef typename mpl::eval_if<
|
||||
mpl::is_na<supplied_hash_type>,
|
||||
index_args_default_hash<key_from_value_type>,
|
||||
mpl::identity<supplied_hash_type>
|
||||
>::type hash_type;
|
||||
typedef typename mpl::if_<
|
||||
Arg2> supplied_hash_type;
|
||||
typedef mp11::mp_eval_if_c<
|
||||
!std::is_void<supplied_hash_type>::value,
|
||||
supplied_hash_type,
|
||||
boost::hash,
|
||||
typename key_from_value_type::result_type
|
||||
> hash_type;
|
||||
typedef mp11::mp_if<
|
||||
full_form,
|
||||
Arg4,
|
||||
Arg3>::type supplied_pred_type;
|
||||
typedef typename mpl::eval_if<
|
||||
mpl::is_na<supplied_pred_type>,
|
||||
index_args_default_pred<key_from_value_type>,
|
||||
mpl::identity<supplied_pred_type>
|
||||
>::type pred_type;
|
||||
Arg3> supplied_pred_type;
|
||||
typedef mp11::mp_eval_if_c<
|
||||
!std::is_void<supplied_pred_type>::value,
|
||||
supplied_pred_type,
|
||||
std::equal_to,
|
||||
typename key_from_value_type::result_type
|
||||
> pred_type;
|
||||
|
||||
BOOST_STATIC_ASSERT(is_tag<tag_list_type>::value);
|
||||
BOOST_STATIC_ASSERT(!mpl::is_na<key_from_value_type>::value);
|
||||
BOOST_STATIC_ASSERT(!mpl::is_na<hash_type>::value);
|
||||
BOOST_STATIC_ASSERT(!mpl::is_na<pred_type>::value);
|
||||
BOOST_STATIC_ASSERT(!std::is_void<key_from_value_type>::value);
|
||||
BOOST_STATIC_ASSERT(!std::is_void<hash_type>::value);
|
||||
BOOST_STATIC_ASSERT(!std::is_void<pred_type>::value);
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2026 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,19 +9,16 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/multi_index/detail/hash_index_proxy.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
@@ -30,148 +27,156 @@ namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* An iterator template for nodes of multi_index::detail::hashed_index.
|
||||
* Built with the aid boost::forward_iterator_helper from
|
||||
* boost/operators.hpp.
|
||||
/* Iterator class for hashed indices.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
template<typename Node,typename BucketArray>
|
||||
struct hashed_index_global_iterator_tag{};
|
||||
struct hashed_index_local_iterator_tag{};
|
||||
|
||||
template<
|
||||
typename Node,typename BucketArray,
|
||||
typename IndexCategory,typename IteratorCategory
|
||||
>
|
||||
class hashed_index_iterator:
|
||||
public boost::forward_iterator_helper<
|
||||
hashed_index_iterator<Node,BucketArray>,
|
||||
public forward_iterator_helper<
|
||||
hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
const typename Node::value_type*,
|
||||
const typename Node::value_type&>,
|
||||
public safe_iterator<hashed_index_proxy<Node,BucketArray> >
|
||||
#else
|
||||
template<typename Node,typename BucketArray,typename Container>
|
||||
class hashed_index_iterator:
|
||||
public boost::forward_iterator_helper<
|
||||
hashed_index_iterator<Node,BucketArray,Container>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
const typename Node::value_type*,
|
||||
const typename Node::value_type&>,
|
||||
public safe_iterator<Container>
|
||||
#endif
|
||||
#else
|
||||
template<typename Node,typename BucketArray>
|
||||
class hashed_index_iterator:
|
||||
public boost::forward_iterator_helper<
|
||||
hashed_index_iterator<Node,BucketArray>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
typename Node::difference_type,
|
||||
const typename Node::value_type*,
|
||||
const typename Node::value_type&>
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
public:
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
typedef hashed_index_proxy<Node,BucketArray> container_type;
|
||||
#else
|
||||
typedef Container container_type;
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef safe_iterator<container_type> safe_super;
|
||||
|
||||
public:
|
||||
hashed_index_iterator():node(0),buckets(0){}
|
||||
hashed_index_iterator(
|
||||
Node* node_,BucketArray& buckets_,container_type* cont_):
|
||||
safe_super(cont_),node(node_),buckets(&buckets_){}
|
||||
|
||||
hashed_index_iterator& operator=(const hashed_index_iterator& x)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x);
|
||||
safe_super::operator=(x);
|
||||
node=x.node;
|
||||
buckets=x.buckets;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#else
|
||||
public:
|
||||
/* coverity[uninit_ctor]: suppress warning */
|
||||
hashed_index_iterator(){}
|
||||
hashed_index_iterator(Node* node_,BucketArray& buckets_):
|
||||
node(node_),buckets(&buckets_){}
|
||||
#endif
|
||||
hashed_index_iterator(Node* node_):node(node_){}
|
||||
|
||||
const typename Node::value_type& operator*()const
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this);
|
||||
return node->value;
|
||||
return node->value();
|
||||
}
|
||||
|
||||
hashed_index_iterator& operator++()
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
|
||||
BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this);
|
||||
Node::increment(node,buckets->begin(),buckets->end());
|
||||
this->increment(IteratorCategory());
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend bool operator==(const hashed_index_iterator& x,const hashed_index_iterator& y)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(y);
|
||||
BOOST_MULTI_INDEX_CHECK_SAME_OWNER(x,y);
|
||||
return x.node==y.node;
|
||||
}
|
||||
|
||||
/* get_node is not to be used by the user */
|
||||
|
||||
Node* get_node()const{return node;}
|
||||
|
||||
private:
|
||||
Node* node;
|
||||
BucketArray* buckets;
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
/* Serialization. As for why the following is public,
|
||||
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
|
||||
*/
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,const unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive& ar,const unsigned int version)const
|
||||
void save(Archive& ar,const unsigned int)const
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
|
||||
node_base_type* bnode=node;
|
||||
ar<<serialization::make_nvp("pointer",bnode);
|
||||
ar<<serialization::make_nvp("pointer",buckets);
|
||||
node_base_type* bnode=get_node();
|
||||
ar<<core::make_nvp("pointer",bnode);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int version)
|
||||
{
|
||||
load(ar,version,IteratorCategory());
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(
|
||||
Archive& ar,const unsigned int version,hashed_index_global_iterator_tag)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
node=static_cast<Node*>(bnode);
|
||||
ar>>serialization::make_nvp("pointer",buckets);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::uncheck();
|
||||
#endif
|
||||
ar>>core::make_nvp("pointer",bnode);
|
||||
node=typename Node::pointer(static_cast<Node*>(bnode));
|
||||
if(version<1){
|
||||
BucketArray* throw_away; /* consume unused ptr */
|
||||
ar>>core::make_nvp("pointer",throw_away);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(
|
||||
Archive& ar,const unsigned int version,hashed_index_local_iterator_tag)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>core::make_nvp("pointer",bnode);
|
||||
node=typename Node::pointer(static_cast<Node*>(bnode));
|
||||
if(version<1){
|
||||
BucketArray* buckets;
|
||||
ar>>core::make_nvp("pointer",buckets);
|
||||
if(buckets&&bnode&&node->impl()==buckets->end()->prior()){
|
||||
/* end local_iterators used to point to end node, now they are null */
|
||||
node=typename Node::pointer(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* get_node is not to be used by the user */
|
||||
|
||||
typedef Node node_type;
|
||||
|
||||
Node* get_node()const{return raw_ptr<Node*>(node);}
|
||||
|
||||
private:
|
||||
|
||||
void increment(hashed_index_global_iterator_tag)
|
||||
{
|
||||
Node::template increment<IndexCategory>(node);
|
||||
}
|
||||
|
||||
void increment(hashed_index_local_iterator_tag)
|
||||
{
|
||||
Node::template increment_local<IndexCategory>(node);
|
||||
}
|
||||
|
||||
typename Node::pointer node;
|
||||
};
|
||||
|
||||
template<
|
||||
typename Node,typename BucketArray,
|
||||
typename IndexCategory,typename IteratorCategory
|
||||
>
|
||||
bool operator==(
|
||||
const hashed_index_iterator<
|
||||
Node,BucketArray,IndexCategory,IteratorCategory>& x,
|
||||
const hashed_index_iterator<
|
||||
Node,BucketArray,IndexCategory,IteratorCategory>& y)
|
||||
{
|
||||
return x.get_node()==y.get_node();
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* class version = 1 : hashed_index_iterator does no longer serialize a bucket
|
||||
* array pointer.
|
||||
*/
|
||||
|
||||
namespace serialization {
|
||||
template<
|
||||
typename Node,typename BucketArray,
|
||||
typename IndexCategory,typename IteratorCategory
|
||||
>
|
||||
struct version<
|
||||
boost::multi_index::detail::hashed_index_iterator<
|
||||
Node,BucketArray,IndexCategory,IteratorCategory
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int,value=1);
|
||||
};
|
||||
} /* namespace serialization */
|
||||
#endif
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_FWD_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
template<typename Node,typename BucketArray>
|
||||
class hashed_index_iterator;
|
||||
#else
|
||||
template<typename Node,typename BucketArray,typename Container>
|
||||
class hashed_index_iterator;
|
||||
#endif
|
||||
#else
|
||||
template<typename Node,typename BucketArray>
|
||||
class hashed_index_iterator;
|
||||
#endif
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2026 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,12 +9,14 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <functional>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -22,107 +24,753 @@ namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* singly-linked node for use by hashed_index */
|
||||
/* Certain C++ requirements on unordered associative containers (see LWG issue
|
||||
* #579) imply a data structure where nodes are linked in a single list, which
|
||||
* in its turn forces implementors to add additional overhed per node to
|
||||
* associate each with its corresponding bucket. Others resort to storing hash
|
||||
* values, we use an alternative structure providing unconditional O(1)
|
||||
* manipulation, even in situations of unfair hash distribution, plus some
|
||||
* lookup speedups. For unique indices we maintain a doubly linked list of
|
||||
* nodes except that if N is the first node of a bucket its associated
|
||||
* bucket node is embedded between N and the preceding node in the following
|
||||
* manner:
|
||||
*
|
||||
* +---+ +---+ +---+ +---+
|
||||
* <--+ |<--+ | <--+ |<--+ |
|
||||
* ... | B0| | B1| ... | B1| | B2| ...
|
||||
* | |-+ | +--> | |-+ | +-->
|
||||
* +-+-+ | +---+ +-+-+ | +---+
|
||||
* | ^ | ^
|
||||
* | | | |
|
||||
* | +-+ | +-+
|
||||
* | | | |
|
||||
* v | v |
|
||||
* --+---+---+---+-- --+---+---+---+--
|
||||
* ... | | B1| | ... | | B2| | ...
|
||||
* --+---+---+---+-- --+---+---+---+--
|
||||
*
|
||||
*
|
||||
* The fist and last nodes of buckets can be checked with
|
||||
*
|
||||
* first node of a bucket: Npn != N
|
||||
* last node of a bucket: Nnp != N
|
||||
*
|
||||
* (n and p short for ->next(), ->prior(), bucket nodes have prior pointers
|
||||
* only). Pure insert and erase (without lookup) can be unconditionally done
|
||||
* in O(1).
|
||||
* For non-unique indices we add the following additional complexity: when
|
||||
* there is a group of 3 or more equivalent elements, they are linked as
|
||||
* follows:
|
||||
*
|
||||
* +-----------------------+
|
||||
* | v
|
||||
* +---+ | +---+ +---+ +---+
|
||||
* | | +-+ | | |<--+ |
|
||||
* | F | | S | ... | P | | L |
|
||||
* | +-->| | | +-+ | |
|
||||
* +---+ +---+ +---+ | +---+
|
||||
* ^ |
|
||||
* +-----------------------+
|
||||
*
|
||||
* F, S, P and L are the first, second, penultimate and last node in the
|
||||
* group, respectively (S and P can coincide if the group has size 3.) This
|
||||
* arrangement is used to skip equivalent elements in O(1) when doing lookup,
|
||||
* while preserving O(1) insert/erase. The following invariants identify
|
||||
* special positions (some of the operations have to be carefully implemented
|
||||
* as Xnn is not valid if Xn points to a bucket):
|
||||
*
|
||||
* first node of a bucket: Npnp == N
|
||||
* last node of a bucket: Nnpp == N
|
||||
* first node of a group: Nnp != N && Nnppn == N
|
||||
* second node of a group: Npn != N && Nppnn == N
|
||||
* n-1 node of a group: Nnp != N && Nnnpp == N
|
||||
* last node of a group: Npn != N && Npnnp == N
|
||||
*
|
||||
* The memory overhead is one pointer per bucket plus two pointers per node,
|
||||
* probably unbeatable. The resulting structure is bidirectonally traversable,
|
||||
* though currently we are just providing forward iteration.
|
||||
*/
|
||||
|
||||
struct hashed_index_node_impl
|
||||
template<typename Allocator>
|
||||
struct hashed_index_node_impl;
|
||||
|
||||
/* half-header (only prior() pointer) to use for the bucket array */
|
||||
|
||||
template<typename Allocator>
|
||||
struct hashed_index_base_node_impl
|
||||
{
|
||||
hashed_index_node_impl*& next(){return next_;}
|
||||
hashed_index_node_impl*const & next()const{return next_;}
|
||||
typedef allocator_rebind_t<
|
||||
Allocator,hashed_index_base_node_impl
|
||||
> base_allocator;
|
||||
typedef allocator_rebind_t<
|
||||
Allocator,hashed_index_node_impl<Allocator>
|
||||
> node_allocator;
|
||||
typedef allocator_pointer_t<base_allocator> base_pointer;
|
||||
typedef allocator_const_pointer_t<base_allocator> const_base_pointer;
|
||||
typedef allocator_pointer_t<node_allocator> pointer;
|
||||
typedef allocator_const_pointer_t<node_allocator> const_pointer;
|
||||
typedef allocator_difference_type_t<node_allocator> difference_type;
|
||||
|
||||
/* interoperability with hashed_index_proxy */
|
||||
pointer& prior(){return prior_;}
|
||||
pointer prior()const{return prior_;}
|
||||
|
||||
static hashed_index_node_impl* end(hashed_index_node_impl* header)
|
||||
private:
|
||||
pointer prior_;
|
||||
};
|
||||
|
||||
/* full header (prior() and next()) for the nodes */
|
||||
|
||||
template<typename Allocator>
|
||||
struct hashed_index_node_impl:hashed_index_base_node_impl<Allocator>
|
||||
{
|
||||
private:
|
||||
typedef hashed_index_base_node_impl<Allocator> super;
|
||||
|
||||
public:
|
||||
typedef typename super::base_pointer base_pointer;
|
||||
typedef typename super::const_base_pointer const_base_pointer;
|
||||
typedef typename super::pointer pointer;
|
||||
typedef typename super::const_pointer const_pointer;
|
||||
|
||||
base_pointer& next(){return next_;}
|
||||
base_pointer next()const{return next_;}
|
||||
|
||||
static pointer pointer_from(base_pointer x)
|
||||
{
|
||||
return header;
|
||||
return static_cast<pointer>(
|
||||
static_cast<hashed_index_node_impl*>(
|
||||
raw_ptr<super*>(x)));
|
||||
}
|
||||
|
||||
/* algorithmic stuff */
|
||||
|
||||
static void increment(
|
||||
hashed_index_node_impl*& x,
|
||||
hashed_index_node_impl* bbegin,hashed_index_node_impl* bbend)
|
||||
static base_pointer base_pointer_from(pointer x)
|
||||
{
|
||||
std::less_equal<hashed_index_node_impl*> leq;
|
||||
return static_cast<base_pointer>(
|
||||
raw_ptr<hashed_index_node_impl*>(x));
|
||||
}
|
||||
|
||||
x=x->next();
|
||||
if(leq(bbegin,x)&&leq(x,bbend)){ /* bucket node */
|
||||
do{
|
||||
++x;
|
||||
}while(x->next()==x);
|
||||
x=x->next();
|
||||
private:
|
||||
base_pointer next_;
|
||||
};
|
||||
|
||||
/* Boost.MultiIndex requires machinery to reverse unlink operations. A simple
|
||||
* way to make a pointer-manipulation function undoable is to templatize
|
||||
* its internal pointer assignments with a functor that, besides doing the
|
||||
* assignment, keeps track of the original pointer values and can later undo
|
||||
* the operations in reverse order.
|
||||
*/
|
||||
|
||||
struct default_assigner
|
||||
{
|
||||
template<typename T> void operator()(T& x,const T& val){x=val;}
|
||||
};
|
||||
|
||||
template<typename Node>
|
||||
struct unlink_undo_assigner
|
||||
{
|
||||
typedef typename Node::base_pointer base_pointer;
|
||||
typedef typename Node::pointer pointer;
|
||||
|
||||
unlink_undo_assigner():pointer_track_count(0),base_pointer_track_count(0){}
|
||||
|
||||
void operator()(pointer& x,pointer val)
|
||||
{
|
||||
pointer_tracks[pointer_track_count].x=&x;
|
||||
pointer_tracks[pointer_track_count++].val=x;
|
||||
x=val;
|
||||
}
|
||||
|
||||
void operator()(base_pointer& x,base_pointer val)
|
||||
{
|
||||
base_pointer_tracks[base_pointer_track_count].x=&x;
|
||||
base_pointer_tracks[base_pointer_track_count++].val=x;
|
||||
x=val;
|
||||
}
|
||||
|
||||
void operator()() /* undo op */
|
||||
{
|
||||
/* in the absence of aliasing, restitution order is immaterial */
|
||||
|
||||
while(pointer_track_count--){
|
||||
*(pointer_tracks[pointer_track_count].x)=
|
||||
pointer_tracks[pointer_track_count].val;
|
||||
}
|
||||
while(base_pointer_track_count--){
|
||||
*(base_pointer_tracks[base_pointer_track_count].x)=
|
||||
base_pointer_tracks[base_pointer_track_count].val;
|
||||
}
|
||||
}
|
||||
|
||||
static void link(
|
||||
hashed_index_node_impl* x,hashed_index_node_impl* pos)
|
||||
{
|
||||
x->next()=pos->next();
|
||||
pos->next()=x;
|
||||
};
|
||||
struct pointer_track {pointer* x; pointer val;};
|
||||
struct base_pointer_track{base_pointer* x; base_pointer val;};
|
||||
|
||||
static void unlink(hashed_index_node_impl* x)
|
||||
/* We know the maximum number of pointer and base pointer assignments that
|
||||
* the two unlink versions do, so we can statically reserve the needed
|
||||
* storage.
|
||||
*/
|
||||
|
||||
pointer_track pointer_tracks[3];
|
||||
int pointer_track_count;
|
||||
base_pointer_track base_pointer_tracks[2];
|
||||
int base_pointer_track_count;
|
||||
};
|
||||
|
||||
/* algorithmic stuff for unique and non-unique variants */
|
||||
|
||||
struct hashed_unique_tag{};
|
||||
struct hashed_non_unique_tag{};
|
||||
|
||||
template<typename Node,typename Category>
|
||||
struct hashed_index_node_alg;
|
||||
|
||||
template<typename Node>
|
||||
struct hashed_index_node_alg<Node,hashed_unique_tag>
|
||||
{
|
||||
typedef typename Node::base_pointer base_pointer;
|
||||
typedef typename Node::const_base_pointer const_base_pointer;
|
||||
typedef typename Node::pointer pointer;
|
||||
typedef typename Node::const_pointer const_pointer;
|
||||
|
||||
static bool is_first_of_bucket(pointer x)
|
||||
{
|
||||
hashed_index_node_impl* y=x->next();
|
||||
while(y->next()!=x){y=y->next();}
|
||||
y->next()=x->next();
|
||||
return x->prior()->next()!=base_pointer_from(x);
|
||||
}
|
||||
|
||||
static hashed_index_node_impl* prev(hashed_index_node_impl* x)
|
||||
static pointer after(pointer x)
|
||||
{
|
||||
hashed_index_node_impl* y=x->next();
|
||||
while(y->next()!=x){y=y->next();}
|
||||
return y;
|
||||
return is_last_of_bucket(x)?x->next()->prior():pointer_from(x->next());
|
||||
}
|
||||
|
||||
static void unlink_next(hashed_index_node_impl* x)
|
||||
static pointer after_local(pointer x)
|
||||
{
|
||||
x->next()=x->next()->next();
|
||||
return is_last_of_bucket(x)?pointer(0):pointer_from(x->next());
|
||||
}
|
||||
|
||||
static pointer next_to_inspect(pointer x)
|
||||
{
|
||||
return is_last_of_bucket(x)?pointer(0):pointer_from(x->next());
|
||||
}
|
||||
|
||||
static void link(pointer x,base_pointer buc,pointer end)
|
||||
{
|
||||
if(buc->prior()==pointer(0)){ /* empty bucket */
|
||||
x->prior()=end->prior();
|
||||
x->next()=end->prior()->next();
|
||||
x->prior()->next()=buc;
|
||||
buc->prior()=x;
|
||||
end->prior()=x;
|
||||
}
|
||||
else{
|
||||
x->prior()=buc->prior()->prior();
|
||||
x->next()=base_pointer_from(buc->prior());
|
||||
buc->prior()=x;
|
||||
x->next()->prior()=x;
|
||||
}
|
||||
}
|
||||
|
||||
static void unlink(pointer x)
|
||||
{
|
||||
default_assigner assign;
|
||||
unlink(x,assign);
|
||||
}
|
||||
|
||||
typedef unlink_undo_assigner<Node> unlink_undo;
|
||||
|
||||
template<typename Assigner>
|
||||
static void unlink(pointer x,Assigner& assign)
|
||||
{
|
||||
if(is_first_of_bucket(x)){
|
||||
if(is_last_of_bucket(x)){
|
||||
assign(x->prior()->next()->prior(),pointer(0));
|
||||
assign(x->prior()->next(),x->next());
|
||||
assign(x->next()->prior()->prior(),x->prior());
|
||||
}
|
||||
else{
|
||||
assign(x->prior()->next()->prior(),pointer_from(x->next()));
|
||||
assign(x->next()->prior(),x->prior());
|
||||
}
|
||||
}
|
||||
else if(is_last_of_bucket(x)){
|
||||
assign(x->prior()->next(),x->next());
|
||||
assign(x->next()->prior()->prior(),x->prior());
|
||||
}
|
||||
else{
|
||||
assign(x->prior()->next(),x->next());
|
||||
assign(x->next()->prior(),x->prior());
|
||||
}
|
||||
}
|
||||
|
||||
/* used only at rehashing */
|
||||
|
||||
static void append(pointer x,pointer end)
|
||||
{
|
||||
x->prior()=end->prior();
|
||||
x->next()=end->prior()->next();
|
||||
x->prior()->next()=base_pointer_from(x);
|
||||
end->prior()=x;
|
||||
}
|
||||
|
||||
static bool unlink_last(pointer end)
|
||||
{
|
||||
/* returns true iff bucket is emptied */
|
||||
|
||||
pointer x=end->prior();
|
||||
if(x->prior()->next()==base_pointer_from(x)){
|
||||
x->prior()->next()=x->next();
|
||||
end->prior()=x->prior();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
x->prior()->next()->prior()=pointer(0);
|
||||
x->prior()->next()=x->next();
|
||||
end->prior()=x->prior();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
hashed_index_node_impl();
|
||||
static pointer pointer_from(base_pointer x)
|
||||
{
|
||||
return Node::pointer_from(x);
|
||||
}
|
||||
|
||||
hashed_index_node_impl* next_;
|
||||
static base_pointer base_pointer_from(pointer x)
|
||||
{
|
||||
return Node::base_pointer_from(x);
|
||||
}
|
||||
|
||||
static bool is_last_of_bucket(pointer x)
|
||||
{
|
||||
return x->next()->prior()!=x;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Node>
|
||||
struct hashed_index_node_alg<Node,hashed_non_unique_tag>
|
||||
{
|
||||
typedef typename Node::base_pointer base_pointer;
|
||||
typedef typename Node::const_base_pointer const_base_pointer;
|
||||
typedef typename Node::pointer pointer;
|
||||
typedef typename Node::const_pointer const_pointer;
|
||||
|
||||
static bool is_first_of_bucket(pointer x)
|
||||
{
|
||||
return x->prior()->next()->prior()==x;
|
||||
}
|
||||
|
||||
static bool is_first_of_group(pointer x)
|
||||
{
|
||||
return
|
||||
x->next()->prior()!=x&&
|
||||
x->next()->prior()->prior()->next()==base_pointer_from(x);
|
||||
}
|
||||
|
||||
static pointer after(pointer x)
|
||||
{
|
||||
if(x->next()->prior()==x)return pointer_from(x->next());
|
||||
if(x->next()->prior()->prior()==x)return x->next()->prior();
|
||||
if(x->next()->prior()->prior()->next()==base_pointer_from(x))
|
||||
return pointer_from(x->next());
|
||||
return pointer_from(x->next())->next()->prior();
|
||||
}
|
||||
|
||||
static pointer after_local(pointer x)
|
||||
{
|
||||
if(x->next()->prior()==x)return pointer_from(x->next());
|
||||
if(x->next()->prior()->prior()==x)return pointer(0);
|
||||
if(x->next()->prior()->prior()->next()==base_pointer_from(x))
|
||||
return pointer_from(x->next());
|
||||
return pointer_from(x->next())->next()->prior();
|
||||
}
|
||||
|
||||
static pointer next_to_inspect(pointer x)
|
||||
{
|
||||
if(x->next()->prior()==x)return pointer_from(x->next());
|
||||
if(x->next()->prior()->prior()==x)return pointer(0);
|
||||
if(x->next()->prior()->next()->prior()!=x->next()->prior())
|
||||
return pointer(0);
|
||||
return pointer_from(x->next()->prior()->next());
|
||||
}
|
||||
|
||||
static void link(pointer x,base_pointer buc,pointer end)
|
||||
{
|
||||
if(buc->prior()==pointer(0)){ /* empty bucket */
|
||||
x->prior()=end->prior();
|
||||
x->next()=end->prior()->next();
|
||||
x->prior()->next()=buc;
|
||||
buc->prior()=x;
|
||||
end->prior()=x;
|
||||
}
|
||||
else{
|
||||
x->prior()=buc->prior()->prior();
|
||||
x->next()=base_pointer_from(buc->prior());
|
||||
buc->prior()=x;
|
||||
x->next()->prior()=x;
|
||||
}
|
||||
}
|
||||
|
||||
static void link(pointer x,pointer first,pointer last)
|
||||
{
|
||||
x->prior()=first->prior();
|
||||
x->next()=base_pointer_from(first);
|
||||
if(is_first_of_bucket(first)){
|
||||
x->prior()->next()->prior()=x;
|
||||
}
|
||||
else{
|
||||
x->prior()->next()=base_pointer_from(x);
|
||||
}
|
||||
|
||||
if(first==last){
|
||||
last->prior()=x;
|
||||
}
|
||||
else if(first->next()==base_pointer_from(last)){
|
||||
first->prior()=last;
|
||||
first->next()=base_pointer_from(x);
|
||||
}
|
||||
else{
|
||||
pointer second=pointer_from(first->next()),
|
||||
lastbutone=last->prior();
|
||||
second->prior()=first;
|
||||
first->prior()=last;
|
||||
lastbutone->next()=base_pointer_from(x);
|
||||
}
|
||||
}
|
||||
|
||||
static void unlink(pointer x)
|
||||
{
|
||||
default_assigner assign;
|
||||
unlink(x,assign);
|
||||
}
|
||||
|
||||
typedef unlink_undo_assigner<Node> unlink_undo;
|
||||
|
||||
template<typename Assigner>
|
||||
static void unlink(pointer x,Assigner& assign)
|
||||
{
|
||||
if(x->prior()->next()==base_pointer_from(x)){
|
||||
if(x->next()->prior()==x){
|
||||
left_unlink(x,assign);
|
||||
right_unlink(x,assign);
|
||||
}
|
||||
else if(x->next()->prior()->prior()==x){ /* last of bucket */
|
||||
left_unlink(x,assign);
|
||||
right_unlink_last_of_bucket(x,assign);
|
||||
}
|
||||
else if(x->next()->prior()->prior()->next()==
|
||||
base_pointer_from(x)){ /* first of group size */
|
||||
left_unlink(x,assign);
|
||||
right_unlink_first_of_group(x,assign);
|
||||
}
|
||||
else{ /* n-1 of group */
|
||||
unlink_last_but_one_of_group(x,assign);
|
||||
}
|
||||
}
|
||||
else if(x->prior()->next()->prior()==x){ /* first of bucket */
|
||||
if(x->next()->prior()==x){
|
||||
left_unlink_first_of_bucket(x,assign);
|
||||
right_unlink(x,assign);
|
||||
}
|
||||
else if(x->next()->prior()->prior()==x){ /* last of bucket */
|
||||
assign(x->prior()->next()->prior(),pointer(0));
|
||||
assign(x->prior()->next(),x->next());
|
||||
assign(x->next()->prior()->prior(),x->prior());
|
||||
}
|
||||
else{ /* first of group */
|
||||
left_unlink_first_of_bucket(x,assign);
|
||||
right_unlink_first_of_group(x,assign);
|
||||
}
|
||||
}
|
||||
else if(x->next()->prior()->prior()==x){ /* last of group and bucket */
|
||||
left_unlink_last_of_group(x,assign);
|
||||
right_unlink_last_of_bucket(x,assign);
|
||||
}
|
||||
else if(pointer_from(x->prior()->prior()->next())
|
||||
->next()==base_pointer_from(x)){ /* second of group */
|
||||
unlink_second_of_group(x,assign);
|
||||
}
|
||||
else{ /* last of group, ~(last of bucket) */
|
||||
left_unlink_last_of_group(x,assign);
|
||||
right_unlink(x,assign);
|
||||
}
|
||||
}
|
||||
|
||||
/* used only at rehashing */
|
||||
|
||||
static void link_range(
|
||||
pointer first,pointer last,base_pointer buc,pointer cend)
|
||||
{
|
||||
if(buc->prior()==pointer(0)){ /* empty bucket */
|
||||
first->prior()=cend->prior();
|
||||
last->next()=cend->prior()->next();
|
||||
first->prior()->next()=buc;
|
||||
buc->prior()=first;
|
||||
cend->prior()=last;
|
||||
}
|
||||
else{
|
||||
first->prior()=buc->prior()->prior();
|
||||
last->next()=base_pointer_from(buc->prior());
|
||||
buc->prior()=first;
|
||||
last->next()->prior()=last;
|
||||
}
|
||||
}
|
||||
|
||||
static void append_range(pointer first,pointer last,pointer cend)
|
||||
{
|
||||
first->prior()=cend->prior();
|
||||
last->next()=cend->prior()->next();
|
||||
first->prior()->next()=base_pointer_from(first);
|
||||
cend->prior()=last;
|
||||
}
|
||||
|
||||
static std::pair<pointer,bool> unlink_last_group(pointer end)
|
||||
{
|
||||
/* returns first of group true iff bucket is emptied */
|
||||
|
||||
pointer x=end->prior();
|
||||
if(x->prior()->next()==base_pointer_from(x)){
|
||||
x->prior()->next()=x->next();
|
||||
end->prior()=x->prior();
|
||||
return std::make_pair(x,false);
|
||||
}
|
||||
else if(x->prior()->next()->prior()==x){
|
||||
x->prior()->next()->prior()=pointer(0);
|
||||
x->prior()->next()=x->next();
|
||||
end->prior()=x->prior();
|
||||
return std::make_pair(x,true);
|
||||
}
|
||||
else{
|
||||
pointer y=pointer_from(x->prior()->next());
|
||||
|
||||
if(y->prior()->next()==base_pointer_from(y)){
|
||||
y->prior()->next()=x->next();
|
||||
end->prior()=y->prior();
|
||||
return std::make_pair(y,false);
|
||||
}
|
||||
else{
|
||||
y->prior()->next()->prior()=pointer(0);
|
||||
y->prior()->next()=x->next();
|
||||
end->prior()=y->prior();
|
||||
return std::make_pair(y,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void unlink_range(pointer first,pointer last)
|
||||
{
|
||||
if(is_first_of_bucket(first)){
|
||||
if(is_last_of_bucket(last)){
|
||||
first->prior()->next()->prior()=pointer(0);
|
||||
first->prior()->next()=last->next();
|
||||
last->next()->prior()->prior()=first->prior();
|
||||
}
|
||||
else{
|
||||
first->prior()->next()->prior()=pointer_from(last->next());
|
||||
last->next()->prior()=first->prior();
|
||||
}
|
||||
}
|
||||
else if(is_last_of_bucket(last)){
|
||||
first->prior()->next()=last->next();
|
||||
last->next()->prior()->prior()=first->prior();
|
||||
}
|
||||
else{
|
||||
first->prior()->next()=last->next();
|
||||
last->next()->prior()=first->prior();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static pointer pointer_from(base_pointer x)
|
||||
{
|
||||
return Node::pointer_from(x);
|
||||
}
|
||||
|
||||
static base_pointer base_pointer_from(pointer x)
|
||||
{
|
||||
return Node::base_pointer_from(x);
|
||||
}
|
||||
|
||||
static bool is_last_of_bucket(pointer x)
|
||||
{
|
||||
return x->next()->prior()->prior()==x;
|
||||
}
|
||||
|
||||
template<typename Assigner>
|
||||
static void left_unlink(pointer x,Assigner& assign)
|
||||
{
|
||||
assign(x->prior()->next(),x->next());
|
||||
}
|
||||
|
||||
template<typename Assigner>
|
||||
static void right_unlink(pointer x,Assigner& assign)
|
||||
{
|
||||
assign(x->next()->prior(),x->prior());
|
||||
}
|
||||
|
||||
template<typename Assigner>
|
||||
static void left_unlink_first_of_bucket(pointer x,Assigner& assign)
|
||||
{
|
||||
assign(x->prior()->next()->prior(),pointer_from(x->next()));
|
||||
}
|
||||
|
||||
template<typename Assigner>
|
||||
static void right_unlink_last_of_bucket(pointer x,Assigner& assign)
|
||||
{
|
||||
assign(x->next()->prior()->prior(),x->prior());
|
||||
}
|
||||
|
||||
template<typename Assigner>
|
||||
static void right_unlink_first_of_group(pointer x,Assigner& assign)
|
||||
{
|
||||
pointer second=pointer_from(x->next()),
|
||||
last=second->prior(),
|
||||
lastbutone=last->prior();
|
||||
if(second==lastbutone){
|
||||
assign(second->next(),base_pointer_from(last));
|
||||
assign(second->prior(),x->prior());
|
||||
}
|
||||
else{
|
||||
assign(lastbutone->next(),base_pointer_from(second));
|
||||
assign(second->next()->prior(),last);
|
||||
assign(second->prior(),x->prior());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Assigner>
|
||||
static void left_unlink_last_of_group(pointer x,Assigner& assign)
|
||||
{
|
||||
pointer lastbutone=x->prior(),
|
||||
first=pointer_from(lastbutone->next()),
|
||||
second=pointer_from(first->next());
|
||||
if(lastbutone==second){
|
||||
assign(lastbutone->prior(),first);
|
||||
assign(lastbutone->next(),x->next());
|
||||
}
|
||||
else{
|
||||
assign(second->prior(),lastbutone);
|
||||
assign(lastbutone->prior()->next(),base_pointer_from(first));
|
||||
assign(lastbutone->next(),x->next());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Assigner>
|
||||
static void unlink_last_but_one_of_group(pointer x,Assigner& assign)
|
||||
{
|
||||
pointer first=pointer_from(x->next()),
|
||||
second=pointer_from(first->next()),
|
||||
last=second->prior();
|
||||
if(second==x){
|
||||
assign(last->prior(),first);
|
||||
assign(first->next(),base_pointer_from(last));
|
||||
}
|
||||
else{
|
||||
assign(last->prior(),x->prior());
|
||||
assign(x->prior()->next(),base_pointer_from(first));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Assigner>
|
||||
static void unlink_second_of_group(pointer x,Assigner& assign)
|
||||
{
|
||||
pointer last=x->prior(),
|
||||
lastbutone=last->prior(),
|
||||
first=pointer_from(lastbutone->next());
|
||||
if(lastbutone==x){
|
||||
assign(first->next(),base_pointer_from(last));
|
||||
assign(last->prior(),first);
|
||||
}
|
||||
else{
|
||||
assign(first->next(),x->next());
|
||||
assign(x->next()->prior(),last);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct hashed_index_node_trampoline:hashed_index_node_impl{};
|
||||
struct hashed_index_node_trampoline:
|
||||
hashed_index_node_impl<
|
||||
allocator_rebind_t<
|
||||
typename Super::allocator_type,char
|
||||
>
|
||||
>
|
||||
{
|
||||
typedef allocator_rebind_t<
|
||||
typename Super::allocator_type,char
|
||||
> impl_allocator_type;
|
||||
typedef hashed_index_node_impl<impl_allocator_type> impl_type;
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct hashed_index_node:Super,hashed_index_node_trampoline<Super>
|
||||
struct hashed_index_node:
|
||||
Super,hashed_index_node_trampoline<Super>
|
||||
{
|
||||
hashed_index_node_impl* impl()
|
||||
{return static_cast<impl_type*>(this);}
|
||||
const hashed_index_node_impl* impl()const
|
||||
{return static_cast<const impl_type*>(this);}
|
||||
|
||||
static hashed_index_node* from_impl(hashed_index_node_impl *x)
|
||||
{return static_cast<hashed_index_node*>(static_cast<impl_type*>(x));}
|
||||
static const hashed_index_node* from_impl(
|
||||
const hashed_index_node_impl* x)
|
||||
{
|
||||
return static_cast<const hashed_index_node*>(
|
||||
static_cast<const impl_type*>(x));
|
||||
}
|
||||
|
||||
static void increment(
|
||||
hashed_index_node*& x,
|
||||
hashed_index_node_impl* bbegin,hashed_index_node_impl* bend)
|
||||
{
|
||||
hashed_index_node_impl* xi=x->impl();
|
||||
impl_type::increment(xi,bbegin,bend);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
|
||||
/* interoperability with hashed_index_proxy */
|
||||
|
||||
static hashed_index_node* end(hashed_index_node* header)
|
||||
{
|
||||
return from_impl(impl_type::end(header->impl()));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef hashed_index_node_trampoline<Super> impl_type;
|
||||
typedef hashed_index_node_trampoline<Super> trampoline;
|
||||
|
||||
public:
|
||||
typedef typename trampoline::impl_type impl_type;
|
||||
typedef typename trampoline::base_pointer impl_base_pointer;
|
||||
typedef typename trampoline::const_base_pointer const_impl_base_pointer;
|
||||
typedef typename trampoline::pointer impl_pointer;
|
||||
typedef typename trampoline::const_pointer const_impl_pointer;
|
||||
typedef typename trampoline::difference_type difference_type;
|
||||
typedef allocator_rebind_t<
|
||||
typename trampoline::impl_allocator_type,
|
||||
hashed_index_node> final_allocator_type;
|
||||
typedef allocator_pointer_t<
|
||||
final_allocator_type> pointer;
|
||||
typedef allocator_const_pointer_t<
|
||||
final_allocator_type> const_pointer;
|
||||
|
||||
template<typename Category>
|
||||
struct node_alg{
|
||||
typedef hashed_index_node_alg<impl_type,Category> type;
|
||||
};
|
||||
|
||||
impl_pointer& prior(){return trampoline::prior();}
|
||||
impl_pointer prior()const{return trampoline::prior();}
|
||||
impl_base_pointer& next(){return trampoline::next();}
|
||||
impl_base_pointer next()const{return trampoline::next();}
|
||||
|
||||
impl_pointer impl()
|
||||
{
|
||||
return static_cast<impl_pointer>(
|
||||
static_cast<impl_type*>(static_cast<trampoline*>(this)));
|
||||
}
|
||||
|
||||
const_impl_pointer impl()const
|
||||
{
|
||||
return static_cast<const_impl_pointer>(
|
||||
static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
|
||||
}
|
||||
|
||||
static hashed_index_node* from_impl(impl_pointer x)
|
||||
{
|
||||
return
|
||||
static_cast<hashed_index_node*>(
|
||||
static_cast<trampoline*>(
|
||||
raw_ptr<impl_type*>(x)));
|
||||
}
|
||||
|
||||
static const hashed_index_node* from_impl(const_impl_pointer x)
|
||||
{
|
||||
return
|
||||
static_cast<const hashed_index_node*>(
|
||||
static_cast<const trampoline*>(
|
||||
raw_ptr<const impl_type*>(x)));
|
||||
}
|
||||
|
||||
/* interoperability with hashed_index_iterator */
|
||||
|
||||
template<typename Category>
|
||||
static void increment(pointer& x)
|
||||
{
|
||||
x=pointer(from_impl(node_alg<Category>::type::after(x->impl())));
|
||||
}
|
||||
|
||||
template<typename Category>
|
||||
static void increment_local(pointer& x)
|
||||
{
|
||||
x=pointer(from_impl(node_alg<Category>::type::after_local(x->impl())));
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/* Copyright 2003-2004 Joaquín M López Muñoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_hashed_index_proxy_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_HASH_hashed_index_proxy_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
#include <algorithm>
|
||||
#include <boost/multi_index/detail/hash_index_iterator_fwd.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Analogous of index_proxy for interoperability with
|
||||
* hashed_index_iterator.
|
||||
*/
|
||||
|
||||
template<typename Node,typename BucketArray>
|
||||
class hashed_index_proxy:
|
||||
public safe_container<hashed_index_proxy<Node,BucketArray> >
|
||||
{
|
||||
protected:
|
||||
hashed_index_proxy(Node* header_,BucketArray& buckets_):
|
||||
header(header_),buckets(&buckets_){}
|
||||
|
||||
void swap(hashed_index_proxy<Node,BucketArray>& x)
|
||||
{
|
||||
std::swap(header,x.header);
|
||||
std::swap(buckets,x.buckets);
|
||||
safe_container<hashed_index_proxy<Node,BucketArray> >::swap(x);
|
||||
}
|
||||
|
||||
public:
|
||||
typedef hashed_index_iterator<Node,BucketArray> iterator;
|
||||
typedef hashed_index_iterator<Node,BucketArray> const_iterator;
|
||||
|
||||
hashed_index_iterator<Node,BucketArray> end()const
|
||||
{
|
||||
return hashed_index_iterator<Node,BucketArray>(
|
||||
Node::end(header),*buckets,const_cast<hashed_index_proxy*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
Node* header;
|
||||
BucketArray* buckets;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif /* workaround */
|
||||
|
||||
#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,12 +9,11 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -22,23 +21,23 @@ namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* An utility class derived from base_from_member used to hold
|
||||
* a pointer to the header node. The base from member idiom is used
|
||||
* because index classes, which are superclasses of multi_index_container,
|
||||
* need this header in construction time.
|
||||
* The allocation is made by the allocator of the multi_index_container
|
||||
/* A utility class used to hold a pointer to the header node.
|
||||
* The base from member idiom is used because index classes, which are
|
||||
* superclasses of multi_index_container, need this header in construction
|
||||
* time. The allocation is made by the allocator of the multi_index_container
|
||||
* class --hence, this allocator needs also be stored resorting
|
||||
* to the base from member trick.
|
||||
*/
|
||||
|
||||
template<typename NodeType,typename Final>
|
||||
struct header_holder:base_from_member<NodeType*>,private noncopyable
|
||||
template<typename NodeTypePtr,typename Final>
|
||||
struct header_holder:private noncopyable
|
||||
{
|
||||
header_holder():super(final().allocate_node()){}
|
||||
~header_holder(){final().deallocate_node(super::member);}
|
||||
header_holder():member(final().allocate_node()){}
|
||||
~header_holder(){final().deallocate_node(&*member);}
|
||||
|
||||
NodeTypePtr member;
|
||||
|
||||
private:
|
||||
typedef base_from_member<NodeType*> super;
|
||||
Final& final(){return *static_cast<Final*>(this);}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/* Copyright 2003-2016 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_GCC)&&(BOOST_GCC>=4*10000+6*100)
|
||||
#if !defined(BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#else
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_ACCESS_SEQUENCE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_ACCESS_SEQUENCE_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/multi_index_container_fwd.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Successive access to the indices of a multi_index_container. Used as dst in
|
||||
* backbone function extract_(x,dst) to retrieve the destination indices
|
||||
* where iterators referring to x must be transferred to (in merging
|
||||
* operations).
|
||||
*/
|
||||
|
||||
template<typename MultiIndexContainer,int N=0>
|
||||
struct index_access_sequence;
|
||||
|
||||
struct index_access_sequence_terminal
|
||||
{
|
||||
index_access_sequence_terminal(void*){}
|
||||
};
|
||||
|
||||
template<typename MultiIndexContainer,int N>
|
||||
struct index_access_sequence_normal
|
||||
{
|
||||
MultiIndexContainer* p;
|
||||
|
||||
index_access_sequence_normal(MultiIndexContainer* p_):p(p_){}
|
||||
|
||||
typename nth_index<MultiIndexContainer,N>::type&
|
||||
get(){return p->template get<N>();}
|
||||
|
||||
index_access_sequence<MultiIndexContainer,N+1>
|
||||
next(){return index_access_sequence<MultiIndexContainer,N+1>(p);}
|
||||
};
|
||||
|
||||
template<typename MultiIndexContainer,int N>
|
||||
using index_access_sequence_base=mp11::mp_if_c<
|
||||
N<mp11::mp_size<typename MultiIndexContainer::index_type_list>::value,
|
||||
index_access_sequence_normal<MultiIndexContainer,N>,
|
||||
index_access_sequence_terminal
|
||||
>;
|
||||
|
||||
template<typename MultiIndexContainer,int N>
|
||||
struct index_access_sequence:index_access_sequence_base<MultiIndexContainer,N>
|
||||
{
|
||||
typedef index_access_sequence_base<
|
||||
MultiIndexContainer,N> super;
|
||||
|
||||
index_access_sequence(MultiIndexContainer* p):super(p){}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2026 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,16 +9,20 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/multi_index/detail/copy_map.hpp>
|
||||
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
|
||||
#include <boost/multi_index/detail/index_access_sequence.hpp>
|
||||
#include <boost/multi_index/detail/node_handle.hpp>
|
||||
#include <boost/multi_index/detail/node_type.hpp>
|
||||
#include <boost/multi_index/detail/type_list.hpp>
|
||||
#include <boost/multi_index_container_fwd.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <utility>
|
||||
@@ -42,80 +46,152 @@ namespace detail{
|
||||
* cannot be called directly from the index classes.)
|
||||
*/
|
||||
|
||||
struct lvalue_tag{};
|
||||
struct rvalue_tag{};
|
||||
struct emplaced_tag{};
|
||||
|
||||
template<typename Value,typename IndexSpecifierList,typename Allocator>
|
||||
class index_base
|
||||
{
|
||||
protected:
|
||||
typedef index_node_base<Value> node_type;
|
||||
typedef index_node_base<Value,Allocator> index_node_type;
|
||||
typedef typename multi_index_node_type<
|
||||
Value,IndexSpecifierList,Allocator>::type final_node_type;
|
||||
typedef multi_index_container<
|
||||
Value,IndexSpecifierList,Allocator> final_type;
|
||||
typedef tuples::null_type ctor_args_list;
|
||||
typedef typename
|
||||
boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
typename Allocator::value_type>::type final_allocator_type;
|
||||
typedef mpl::vector0<> index_type_list;
|
||||
typedef mpl::vector0<> iterator_type_list;
|
||||
typedef mpl::vector0<> const_iterator_type_list;
|
||||
typedef Allocator final_allocator_type;
|
||||
typedef node_handle<
|
||||
final_node_type,final_allocator_type> final_node_handle_type;
|
||||
typedef empty_type_list index_type_list;
|
||||
typedef empty_type_list iterator_type_list;
|
||||
typedef empty_type_list const_iterator_type_list;
|
||||
typedef copy_map<
|
||||
final_node_type,
|
||||
final_allocator_type> copy_map_type;
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
typedef index_saver<
|
||||
node_type,
|
||||
index_node_type,
|
||||
final_allocator_type> index_saver_type;
|
||||
typedef index_loader<
|
||||
node_type,
|
||||
index_node_type,
|
||||
final_node_type,
|
||||
final_allocator_type> index_loader_type;
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef typename call_traits<Value>::param_type value_param_type;
|
||||
typedef Value value_type;
|
||||
typedef allocator_size_type_t<Allocator> size_type;
|
||||
|
||||
protected:
|
||||
explicit index_base(const ctor_args_list&,const Allocator&){}
|
||||
explicit index_base(
|
||||
const ctor_args_list&,const Allocator&,index_node_type*){}
|
||||
|
||||
index_base(
|
||||
const index_base<Value,IndexSpecifierList,Allocator>&,
|
||||
const Allocator&,index_node_type*){}
|
||||
|
||||
index_base(
|
||||
const index_base<Value,IndexSpecifierList,Allocator>&,
|
||||
const Allocator&,index_node_type*,
|
||||
do_not_copy_elements_tag)
|
||||
{}
|
||||
|
||||
void copy_(
|
||||
const index_base<Value,IndexSpecifierList,Allocator>&,const copy_map_type&)
|
||||
{}
|
||||
|
||||
node_type* insert_(value_param_type v,node_type* x)
|
||||
final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag)
|
||||
{
|
||||
boost::detail::allocator::construct(&x->value,v);
|
||||
x=final().allocate_node();
|
||||
BOOST_TRY{
|
||||
final().construct_value(x,v);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
final().deallocate_node(x);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return x;
|
||||
}
|
||||
|
||||
node_type* insert_(value_param_type v,node_type*,node_type* x)
|
||||
final_node_type* insert_(const value_type& v,final_node_type*& x,rvalue_tag)
|
||||
{
|
||||
boost::detail::allocator::construct(&x->value,v);
|
||||
x=final().allocate_node();
|
||||
BOOST_TRY{
|
||||
final().construct_value(x,std::move(const_cast<value_type&>(v)));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
final().deallocate_node(x);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return x;
|
||||
}
|
||||
|
||||
void erase_(node_type* x)
|
||||
final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag)
|
||||
{
|
||||
boost::detail::allocator::destroy(&x->value);
|
||||
return x;
|
||||
}
|
||||
|
||||
void delete_node_(node_type* x)
|
||||
template<typename MultiIndexContainer>
|
||||
final_node_type* insert_(
|
||||
const value_type&,final_node_type*& x,MultiIndexContainer* p)
|
||||
{
|
||||
boost::detail::allocator::destroy(&x->value);
|
||||
p->final_extract_for_transfer_(
|
||||
x,index_access_sequence<final_type>(&final()));
|
||||
return x;
|
||||
}
|
||||
|
||||
final_node_type* insert_(
|
||||
const value_type& v,index_node_type*,final_node_type*& x,lvalue_tag)
|
||||
{
|
||||
return insert_(v,x,lvalue_tag());
|
||||
}
|
||||
|
||||
final_node_type* insert_(
|
||||
const value_type& v,index_node_type*,final_node_type*& x,rvalue_tag)
|
||||
{
|
||||
return insert_(v,x,rvalue_tag());
|
||||
}
|
||||
|
||||
final_node_type* insert_(
|
||||
const value_type&,index_node_type*,final_node_type*& x,emplaced_tag)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
void extract_(index_node_type*,Dst){}
|
||||
|
||||
void clear_(){}
|
||||
|
||||
void swap_(index_base<Value,IndexSpecifierList,Allocator>&){}
|
||||
template<typename BoolConstant>
|
||||
void swap_(
|
||||
index_base<Value,IndexSpecifierList,Allocator>&,
|
||||
BoolConstant /* swap_allocators */)
|
||||
{}
|
||||
|
||||
bool replace_(value_param_type v,node_type* x)
|
||||
void swap_elements_(index_base<Value,IndexSpecifierList,Allocator>&){}
|
||||
|
||||
bool replace_(const value_type& v,index_node_type* x,lvalue_tag)
|
||||
{
|
||||
x->value=v;
|
||||
x->value()=v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool modify_(node_type*){return true;}
|
||||
bool replace_(const value_type& v,index_node_type* x,rvalue_tag)
|
||||
{
|
||||
x->value()=std::move(const_cast<value_type&>(v));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool modify_(index_node_type*){return true;}
|
||||
|
||||
bool modify_rollback_(index_node_type*){return true;}
|
||||
|
||||
bool check_rollback_(index_node_type*)const{return true;}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
@@ -138,17 +214,74 @@ protected:
|
||||
final_type& final(){return *static_cast<final_type*>(this);}
|
||||
const final_type& final()const{return *static_cast<const final_type*>(this);}
|
||||
|
||||
template<typename Index>
|
||||
static typename Index::final_type& final(Index& x) /* cross-index access */
|
||||
{return static_cast<typename Index::final_type&>(x);}
|
||||
|
||||
final_node_type* final_header()const{return final().header();}
|
||||
|
||||
bool final_empty_()const{return final().empty_();}
|
||||
std::size_t final_size_()const{return final().size_();}
|
||||
std::size_t final_max_size_()const{return final().max_size_();}
|
||||
bool final_empty_()const{return final().empty_();}
|
||||
size_type final_size_()const{return final().size_();}
|
||||
size_type final_max_size_()const{return final().max_size_();}
|
||||
|
||||
std::pair<final_node_type*,bool> final_insert_(value_param_type x)
|
||||
std::pair<final_node_type*,bool> final_insert_(const value_type& x)
|
||||
{return final().insert_(x);}
|
||||
std::pair<final_node_type*,bool> final_insert_rv_(const value_type& x)
|
||||
{return final().insert_rv_(x);}
|
||||
template<typename T>
|
||||
std::pair<final_node_type*,bool> final_insert_ref_(const T& t)
|
||||
{return final().insert_ref_(t);}
|
||||
template<typename T>
|
||||
std::pair<final_node_type*,bool> final_insert_ref_(T& t)
|
||||
{return final().insert_ref_(t);}
|
||||
std::pair<final_node_type*,bool> final_insert_nh_(final_node_handle_type& nh)
|
||||
{return final().insert_nh_(nh);}
|
||||
|
||||
template<typename Index>
|
||||
std::pair<final_node_type*,bool> final_transfer_(Index& x,final_node_type* n)
|
||||
{return final().transfer_(x,n);}
|
||||
|
||||
template<typename... Args>
|
||||
std::pair<final_node_type*,bool> final_emplace_(Args&&... args)
|
||||
{
|
||||
return final().emplace_(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
std::pair<final_node_type*,bool> final_insert_(
|
||||
value_param_type x,final_node_type* position)
|
||||
const value_type& x,final_node_type* position)
|
||||
{return final().insert_(x,position);}
|
||||
std::pair<final_node_type*,bool> final_insert_rv_(
|
||||
const value_type& x,final_node_type* position)
|
||||
{return final().insert_rv_(x,position);}
|
||||
template<typename T>
|
||||
std::pair<final_node_type*,bool> final_insert_ref_(
|
||||
const T& t,final_node_type* position)
|
||||
{return final().insert_ref_(t,position);}
|
||||
template<typename T>
|
||||
std::pair<final_node_type*,bool> final_insert_ref_(
|
||||
T& t,final_node_type* position)
|
||||
{return final().insert_ref_(t,position);}
|
||||
std::pair<final_node_type*,bool> final_insert_nh_(
|
||||
final_node_handle_type& nh,final_node_type* position)
|
||||
{return final().insert_nh_(nh,position);}
|
||||
|
||||
template<typename... Args>
|
||||
std::pair<final_node_type*,bool> final_emplace_hint_(
|
||||
final_node_type* position,Args&&... args)
|
||||
{
|
||||
return final().emplace_hint_(position,std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
final_node_handle_type final_extract_(final_node_type* x)
|
||||
{
|
||||
return final().extract_(x);
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
void final_extract_for_transfer_(final_node_type* x,Dst dst)
|
||||
{
|
||||
final().extract_for_transfer_(x,dst);
|
||||
}
|
||||
|
||||
void final_erase_(final_node_type* x){final().erase_(x);}
|
||||
|
||||
@@ -156,15 +289,30 @@ protected:
|
||||
void final_delete_all_nodes_(){final().delete_all_nodes_();}
|
||||
void final_clear_(){final().clear_();}
|
||||
|
||||
template<typename Index>
|
||||
void final_transfer_range_(
|
||||
Index& x,
|
||||
typename Index::iterator first,
|
||||
typename Index::iterator last)
|
||||
{final().transfer_range_(x,first,last);}
|
||||
|
||||
void final_swap_(final_type& x){final().swap_(x);}
|
||||
|
||||
bool final_replace_(
|
||||
value_param_type k,final_node_type* x)
|
||||
const value_type& k,final_node_type* x)
|
||||
{return final().replace_(k,x);}
|
||||
bool final_replace_rv_(
|
||||
const value_type& k,final_node_type* x)
|
||||
{return final().replace_rv_(k,x);}
|
||||
|
||||
template<typename Modifier>
|
||||
bool final_modify_(Modifier mod,final_node_type* x)
|
||||
bool final_modify_(Modifier& mod,final_node_type* x)
|
||||
{return final().modify_(mod,x);}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x)
|
||||
{return final().modify_(mod,back,x);}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
||||
void final_check_invariant_()const{final().check_invariant_();}
|
||||
#endif
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_ITERATOR_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_ITERATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/multi_index/detail/index_iterator_fwd.hpp>
|
||||
#include <boost/multi_index/detail/index_proxy.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* An iterator template for nodes of multi_index::detail::index.
|
||||
* Built with the aid boost::bidirectional_iterator_helper from
|
||||
* boost/operators.hpp.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
template<typename Node>
|
||||
class index_iterator:
|
||||
public boost::bidirectional_iterator_helper<
|
||||
index_iterator<Node>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
const typename Node::value_type*,
|
||||
const typename Node::value_type&>,
|
||||
public safe_iterator<index_proxy<Node> >
|
||||
#else
|
||||
template<typename Node,typename Container>
|
||||
class index_iterator:
|
||||
public boost::bidirectional_iterator_helper<
|
||||
index_iterator<Node,Container>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
const typename Node::value_type*,
|
||||
const typename Node::value_type&>,
|
||||
public safe_iterator<Container>
|
||||
#endif
|
||||
#else
|
||||
template<typename Node>
|
||||
class index_iterator:
|
||||
public boost::bidirectional_iterator_helper<
|
||||
index_iterator<Node>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
const typename Node::value_type*,
|
||||
const typename Node::value_type&>
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
public:
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
typedef index_proxy<Node> container_type;
|
||||
#else
|
||||
typedef Container container_type;
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef safe_iterator<container_type> safe_super;
|
||||
|
||||
public:
|
||||
index_iterator():node(0){}
|
||||
index_iterator(Node* node_,container_type* cont_):
|
||||
safe_super(cont_),node(node_){}
|
||||
|
||||
index_iterator& operator=(const index_iterator& x)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x);
|
||||
safe_super::operator=(x);
|
||||
node=x.node;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#else
|
||||
public:
|
||||
index_iterator(){}
|
||||
index_iterator(Node* node_):node(node_){}
|
||||
#endif
|
||||
|
||||
const typename Node::value_type& operator*()const
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this);
|
||||
return node->value;
|
||||
}
|
||||
|
||||
index_iterator& operator++()
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
|
||||
BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this);
|
||||
Node::increment(node);
|
||||
return *this;
|
||||
}
|
||||
|
||||
index_iterator& operator--()
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
|
||||
BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(*this);
|
||||
Node::decrement(node);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend bool operator==(const index_iterator& x,const index_iterator& y)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(y);
|
||||
BOOST_MULTI_INDEX_CHECK_SAME_OWNER(x,y);
|
||||
return x.node==y.node;
|
||||
}
|
||||
|
||||
/* get_node is not to be used by the user */
|
||||
|
||||
Node* get_node()const{return node;}
|
||||
|
||||
private:
|
||||
Node* node;
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive& ar,const unsigned int version)const
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this);
|
||||
node_base_type* bnode=node;
|
||||
ar<<serialization::make_nvp("pointer",bnode);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int version)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
node=static_cast<Node*>(bnode);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::uncheck();
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_ITERATOR_FWD_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_ITERATOR_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
template<typename Node>
|
||||
class index_iterator;
|
||||
#else
|
||||
template<typename Node,typename Container>
|
||||
class index_iterator;
|
||||
#endif
|
||||
#else
|
||||
template<typename Node>
|
||||
class index_iterator;
|
||||
#endif
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,16 +9,17 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/multi_index/detail/bad_archive_exception.hpp>
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -29,7 +30,8 @@ namespace multi_index{
|
||||
namespace detail{
|
||||
|
||||
/* Counterpart of index_saver (check index_saver.hpp for serialization
|
||||
* details.)* multi_index_container is in charge of supplying the info about
|
||||
* details.)
|
||||
* multi_index_container is in charge of supplying the info about
|
||||
* the base sequence, and each index can subsequently load itself using the
|
||||
* const interface of index_loader.
|
||||
*/
|
||||
@@ -46,14 +48,14 @@ public:
|
||||
template<class Archive>
|
||||
void add(Node* node,Archive& ar,const unsigned int)
|
||||
{
|
||||
ar>>serialization::make_nvp("position",*node);
|
||||
ar>>core::make_nvp("position",*node);
|
||||
entries()[n++]=node;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void add_track(Node* node,Archive& ar,const unsigned int)
|
||||
{
|
||||
ar>>serialization::make_nvp("position",*node);
|
||||
ar>>core::make_nvp("position",*node);
|
||||
}
|
||||
|
||||
/* A rearranger is passed two nodes, and is expected to
|
||||
@@ -91,7 +93,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Node** entries()const{return spc.data();}
|
||||
Node** entries()const{return raw_ptr<Node**>(spc.data());}
|
||||
|
||||
/* We try to delay sorting as much as possible just in case it
|
||||
* is not necessary, hence this version of load_node.
|
||||
@@ -101,7 +103,7 @@ private:
|
||||
FinalNode* unchecked_load_node(Archive& ar)const
|
||||
{
|
||||
Node* node=0;
|
||||
ar>>serialization::make_nvp("pointer",node);
|
||||
ar>>core::make_nvp("pointer",node);
|
||||
return static_cast<FinalNode*>(node);
|
||||
}
|
||||
|
||||
@@ -109,7 +111,7 @@ private:
|
||||
FinalNode* load_node(Archive& ar)const
|
||||
{
|
||||
Node* node=0;
|
||||
ar>>serialization::make_nvp("pointer",node);
|
||||
ar>>core::make_nvp("pointer",node);
|
||||
check_node(node);
|
||||
return static_cast<FinalNode*>(node);
|
||||
}
|
||||
@@ -117,9 +119,7 @@ private:
|
||||
void check_node(Node* node)const
|
||||
{
|
||||
if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){
|
||||
throw_exception(
|
||||
archive::archive_exception(
|
||||
archive::archive_exception::other_exception));
|
||||
throw_exception(bad_archive_exception());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,14 +9,15 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
||||
@@ -106,14 +107,14 @@ class algorithm_base:private noncopyable
|
||||
{
|
||||
protected:
|
||||
algorithm_base(const Allocator& al,std::size_t size):
|
||||
spc(al,size),size_(size),n(0),sorted(false)
|
||||
spc(al,size),size_(size),n_(0),sorted(false)
|
||||
{
|
||||
}
|
||||
|
||||
void add(void* node)
|
||||
{
|
||||
entries()[n]=entry(node,n);
|
||||
++n;
|
||||
entries()[n_]=entry(node,n_);
|
||||
++n_;
|
||||
}
|
||||
|
||||
void begin_algorithm()const
|
||||
@@ -179,11 +180,11 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
entry* entries()const{return spc.data();}
|
||||
entry* entries()const{return raw_ptr<entry*>(spc.data());}
|
||||
|
||||
auto_space<entry,Allocator> spc;
|
||||
std::size_t size_;
|
||||
std::size_t n;
|
||||
std::size_t n_;
|
||||
mutable bool sorted;
|
||||
mutable std::size_t num_piles;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,14 +9,17 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/multi_index/detail/bad_archive_exception.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#endif
|
||||
|
||||
@@ -31,16 +34,43 @@ namespace detail{
|
||||
*/
|
||||
|
||||
template<typename Value>
|
||||
struct index_node_base
|
||||
struct pod_value_holder
|
||||
{
|
||||
typename aligned_storage<
|
||||
sizeof(Value),
|
||||
alignment_of<Value>::value
|
||||
>::type space;
|
||||
};
|
||||
|
||||
template<typename Value,typename Allocator>
|
||||
struct index_node_base:private pod_value_holder<Value>
|
||||
{
|
||||
typedef index_node_base base_type; /* used for serialization purposes */
|
||||
typedef Value value_type;
|
||||
value_type value;
|
||||
typedef Allocator allocator_type;
|
||||
|
||||
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
|
||||
|
||||
value_type& value()
|
||||
{
|
||||
return *reinterpret_cast<value_type*>(&this->space);
|
||||
}
|
||||
|
||||
const value_type& value()const
|
||||
{
|
||||
return *reinterpret_cast<const value_type*>(&this->space);
|
||||
}
|
||||
|
||||
#include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
|
||||
|
||||
static index_node_base* from_value(const value_type* p)
|
||||
{
|
||||
return static_cast<index_node_base *>(
|
||||
reinterpret_cast<pod_value_holder<Value>*>( /* std 9.2.17 */
|
||||
const_cast<value_type*>(p)));
|
||||
}
|
||||
|
||||
private:
|
||||
index_node_base();
|
||||
/* this class is not intended to be cted, merely allocated */
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
friend class boost::serialization::access;
|
||||
|
||||
@@ -54,9 +84,16 @@ private:
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template<typename Node,typename Value>
|
||||
Node* node_from_value(const Value* p)
|
||||
{
|
||||
typedef typename Node::allocator_type allocator_type;
|
||||
return static_cast<Node*>(
|
||||
index_node_base<Value,allocator_type>::from_value(p));
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
@@ -68,28 +105,19 @@ private:
|
||||
* somehow invalid archive.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
namespace serialization{
|
||||
#else
|
||||
namespace multi_index{
|
||||
namespace detail{
|
||||
#endif
|
||||
|
||||
template<class Archive,typename Value>
|
||||
template<class Archive,typename Value,typename Allocator>
|
||||
inline void load_construct_data(
|
||||
Archive&,boost::multi_index::detail::index_node_base<Value>*,
|
||||
Archive&,boost::multi_index::detail::index_node_base<Value,Allocator>*,
|
||||
const unsigned int)
|
||||
{
|
||||
throw_exception(
|
||||
archive::archive_exception(archive::archive_exception::other_exception));
|
||||
throw_exception(boost::multi_index::detail::bad_archive_exception());
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
} /* namespace serialization */
|
||||
#else
|
||||
} /* namespace multi_index::detail */
|
||||
} /* namespace multi_index */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_PROXY_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_PROXY_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
#include <algorithm>
|
||||
#include <boost/multi_index/detail/index_iterator_fwd.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* In safe mode, index iterators are derived from safe_iterator<Index>,
|
||||
* where Index is the type of the index where the iterator belongs. Due
|
||||
* to the long symbol names of indices, MSVC++ 6.0 often issues a
|
||||
* LNK1179 (duplicate comdat) error. To workaround this problem,
|
||||
* index_proxy is used instead. index_proxy<Node> acts as an index
|
||||
* over nodes of type Node in all aspects relevant to safe_iterator, and
|
||||
* its shorter symbol name makes life easier for MSVC++ 6.0.
|
||||
*/
|
||||
|
||||
template<typename Node>
|
||||
class index_proxy:public safe_container<index_proxy<Node> >
|
||||
{
|
||||
protected:
|
||||
index_proxy(Node* header_):header(header_){}
|
||||
|
||||
void swap(index_proxy<Node>& x)
|
||||
{
|
||||
std::swap(header,x.header);
|
||||
safe_container<index_proxy<Node> >::swap(x);
|
||||
}
|
||||
|
||||
public:
|
||||
typedef index_iterator<Node> iterator;
|
||||
typedef index_iterator<Node> const_iterator;
|
||||
|
||||
index_iterator<Node> begin()const
|
||||
{
|
||||
return index_iterator<Node>(
|
||||
Node::begin(header),const_cast<index_proxy*>(this));
|
||||
}
|
||||
|
||||
index_iterator<Node> end()const
|
||||
{
|
||||
return index_iterator<Node>(
|
||||
Node::end(header),const_cast<index_proxy*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
Node* header;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif /* workaround */
|
||||
|
||||
#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,14 +9,14 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/multi_index/detail/index_matcher.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost{
|
||||
@@ -43,14 +43,14 @@ public:
|
||||
template<class Archive>
|
||||
void add(Node* node,Archive& ar,const unsigned int)
|
||||
{
|
||||
ar<<serialization::make_nvp("position",*node);
|
||||
ar<<core::make_nvp("position",*node);
|
||||
alg.add(node);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void add_track(Node* node,Archive& ar,const unsigned int)
|
||||
{
|
||||
ar<<serialization::make_nvp("position",*node);
|
||||
ar<<core::make_nvp("position",*node);
|
||||
}
|
||||
|
||||
template<typename IndexIterator,class Archive>
|
||||
@@ -120,7 +120,7 @@ private:
|
||||
template<typename Archive>
|
||||
static void save_node(Node* node,Archive& ar)
|
||||
{
|
||||
ar<<serialization::make_nvp("pointer",node);
|
||||
ar<<core::make_nvp("pointer",node);
|
||||
}
|
||||
|
||||
index_matcher::algorithm<Node,Allocator> alg;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INVALIDATE_ITERATORS_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INVALIDATE_ITERATORS_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* invalidate_iterators mimics the interface of index_access_sequence (see
|
||||
* index_access_sequence.hpp) but returns dummy indices whose iterator type
|
||||
* won't ever match those of the source: the net effect is that safe iterator
|
||||
* transfer resolves to iterator invalidation, so backbone function invocation
|
||||
* extract_(x,invalidate_iterators()) is used in extraction scenarios other
|
||||
* than merging.
|
||||
*/
|
||||
|
||||
struct invalidate_iterators
|
||||
{
|
||||
typedef void iterator;
|
||||
|
||||
invalidate_iterators& get(){return *this;}
|
||||
invalidate_iterators& next(){return *this;}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_FUNCTION_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_IS_FUNCTION_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(_LIBCPP_VERSION,<30700)||\
|
||||
BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40802)
|
||||
/* libc++: std::is_function<void() const> fails,
|
||||
* https://bugs.llvm.org/show_bug.cgi?id=20084
|
||||
*
|
||||
* libstdc++-v3: std::is_function does not support ref-qualified function types,
|
||||
* https://github.com/gcc-mirror/gcc/commit/
|
||||
* 2fa630fb50ba29d8e891c52a75aaec261b07874e#
|
||||
* diff-6547f965a8d66bf35a6388fcf404aaa3
|
||||
*/
|
||||
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
|
||||
namespace boost{namespace multi_index{namespace detail{
|
||||
|
||||
template<typename T>
|
||||
struct is_function:boost::is_function<T>{};
|
||||
|
||||
}}} /* namespace boost::multi_index::detail */
|
||||
|
||||
#else
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{namespace multi_index{namespace detail{
|
||||
|
||||
template<typename T>
|
||||
struct is_function:std::is_function<T>{};
|
||||
|
||||
}}} /* namespace boost::multi_index::detail */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,13 +9,51 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/is_sequence.hpp>
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT)
|
||||
#include <boost/multi_index/detail/mpl_to_mp11_list.hpp>
|
||||
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/mpl/empty.hpp>
|
||||
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/mpl/is_sequence.hpp>
|
||||
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* an index list is a non-empty MPL sequence */
|
||||
|
||||
template<typename T>
|
||||
struct is_index_list
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence<T>::value);
|
||||
BOOST_STATIC_CONSTANT(bool,non_empty=!(std::conditional<
|
||||
mpl_sequence,mpl::empty<T>,std::false_type>::type::value));
|
||||
BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty);
|
||||
};
|
||||
|
||||
template<typename IndexList>
|
||||
using mp11_index_list=mpl_to_mp11_list<IndexList>;
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
#else
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -24,17 +62,19 @@ namespace multi_index{
|
||||
namespace detail{
|
||||
|
||||
template<typename T>
|
||||
struct is_index_list
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence<T>::value);
|
||||
BOOST_STATIC_CONSTANT(bool,non_empty=!mpl::empty<T>::value);
|
||||
BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty);
|
||||
};
|
||||
struct is_index_list:std::false_type{};
|
||||
|
||||
/* an index list is a non-empty Mp11 list */
|
||||
template<template<typename...> class L,typename T,typename... Ts>
|
||||
struct is_index_list<L<T,Ts...>>:std::true_type{};
|
||||
|
||||
template<typename IndexList>
|
||||
using mp11_index_list=IndexList;
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/type_traits/intrinsics.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Metafunction that checks if f(arg,arg2) executes without argument type
|
||||
* conversion. By default (i.e. when it cannot be determined) it evaluates to
|
||||
* true.
|
||||
*/
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2,typename=void>
|
||||
struct is_transparent:std::true_type{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE_EXPR)&& \
|
||||
(defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL))
|
||||
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
#include <boost/type_traits/function_traits.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_final.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
struct not_is_transparent_result_type{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct is_transparent_class_helper:F
|
||||
{
|
||||
using F::operator();
|
||||
template<typename T,typename Q>
|
||||
not_is_transparent_result_type operator()(const T&,const Q&)const;
|
||||
};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2,typename=void>
|
||||
struct is_transparent_class:std::true_type{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct is_transparent_class<
|
||||
F,Arg1,Arg2,
|
||||
typename enable_if<
|
||||
is_same<
|
||||
decltype(
|
||||
declval<const is_transparent_class_helper<F,Arg1,Arg2> >()(
|
||||
declval<const Arg1&>(),declval<const Arg2&>())
|
||||
),
|
||||
not_is_transparent_result_type
|
||||
>
|
||||
>::type
|
||||
>:std::false_type{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct is_transparent<
|
||||
F,Arg1,Arg2,
|
||||
typename enable_if_c<
|
||||
is_class<F>::value&&
|
||||
!is_final<F>::value /* is_transparent_class_helper derives from F */
|
||||
>::type
|
||||
>:is_transparent_class<F,Arg1,Arg2>{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2,typename=void>
|
||||
struct is_transparent_function:std::true_type{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct is_transparent_function<
|
||||
F,Arg1,Arg2,
|
||||
typename enable_if_c<
|
||||
!(is_same<typename function_traits<F>::arg1_type,const Arg1&>::value||
|
||||
is_same<typename function_traits<F>::arg1_type,Arg1>::value)
|
||||
||
|
||||
!(is_same<typename function_traits<F>::arg2_type,const Arg2&>::value||
|
||||
is_same<typename function_traits<F>::arg2_type,Arg2>::value)
|
||||
>::type
|
||||
>:std::false_type{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct is_transparent<
|
||||
F,Arg1,Arg2,
|
||||
typename enable_if<
|
||||
is_function<typename remove_pointer<F>::type>
|
||||
>::type
|
||||
>:is_transparent_function<typename remove_pointer<F>::type,Arg1,Arg2>{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,309 @@
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Poor man's version of boost::iterator_adaptor. Used instead of the
|
||||
* original as compile times for the latter are significantly higher.
|
||||
* The interface is not replicated exactly, only to the extent necessary
|
||||
* for internal consumption.
|
||||
*/
|
||||
|
||||
/* NB. The purpose of the (non-inclass) global operators ==, < and - defined
|
||||
* above is to partially alleviate a problem of MSVC++ 6.0 by * which
|
||||
* friend-injected operators on T are not visible if T is instantiated only
|
||||
* in template code where T is a dependent type.
|
||||
*/
|
||||
|
||||
class iter_adaptor_access
|
||||
{
|
||||
public:
|
||||
template<class Class>
|
||||
static typename Class::reference dereference(const Class& x)
|
||||
{
|
||||
return x.dereference();
|
||||
}
|
||||
|
||||
template<class Class>
|
||||
static bool equal(const Class& x,const Class& y)
|
||||
{
|
||||
return x.equal(y);
|
||||
}
|
||||
|
||||
template<class Class>
|
||||
static void increment(Class& x)
|
||||
{
|
||||
x.increment();
|
||||
}
|
||||
|
||||
template<class Class>
|
||||
static void decrement(Class& x)
|
||||
{
|
||||
x.decrement();
|
||||
}
|
||||
|
||||
template<class Class>
|
||||
static void advance(Class& x,typename Class::difference_type n)
|
||||
{
|
||||
x.advance(n);
|
||||
}
|
||||
|
||||
template<class Class>
|
||||
static typename Class::difference_type distance_to(
|
||||
const Class& x,const Class& y)
|
||||
{
|
||||
return x.distance_to(y);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Category>
|
||||
struct iter_adaptor_selector;
|
||||
|
||||
template<class Derived,class Base>
|
||||
class forward_iter_adaptor_base:
|
||||
public forward_iterator_helper<
|
||||
Derived,
|
||||
typename Base::value_type,
|
||||
typename Base::difference_type,
|
||||
typename Base::pointer,
|
||||
typename Base::reference>
|
||||
{
|
||||
public:
|
||||
typedef typename Base::reference reference;
|
||||
|
||||
reference operator*()const
|
||||
{
|
||||
return iter_adaptor_access::dereference(final());
|
||||
}
|
||||
|
||||
friend bool operator==(const Derived& x,const Derived& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(x,y);
|
||||
}
|
||||
|
||||
Derived& operator++()
|
||||
{
|
||||
iter_adaptor_access::increment(final());
|
||||
return final();
|
||||
}
|
||||
|
||||
private:
|
||||
Derived& final(){return *static_cast<Derived*>(this);}
|
||||
const Derived& final()const{return *static_cast<const Derived*>(this);}
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
bool operator==(
|
||||
const forward_iter_adaptor_base<Derived,Base>& x,
|
||||
const forward_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(
|
||||
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
|
||||
}
|
||||
|
||||
template<>
|
||||
struct iter_adaptor_selector<std::forward_iterator_tag>
|
||||
{
|
||||
template<class Derived,class Base>
|
||||
using fn=forward_iter_adaptor_base<Derived,Base>;
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
class bidirectional_iter_adaptor_base:
|
||||
public bidirectional_iterator_helper<
|
||||
Derived,
|
||||
typename Base::value_type,
|
||||
typename Base::difference_type,
|
||||
typename Base::pointer,
|
||||
typename Base::reference>
|
||||
{
|
||||
public:
|
||||
typedef typename Base::reference reference;
|
||||
|
||||
reference operator*()const
|
||||
{
|
||||
return iter_adaptor_access::dereference(final());
|
||||
}
|
||||
|
||||
friend bool operator==(const Derived& x,const Derived& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(x,y);
|
||||
}
|
||||
|
||||
Derived& operator++()
|
||||
{
|
||||
iter_adaptor_access::increment(final());
|
||||
return final();
|
||||
}
|
||||
|
||||
Derived& operator--()
|
||||
{
|
||||
iter_adaptor_access::decrement(final());
|
||||
return final();
|
||||
}
|
||||
|
||||
private:
|
||||
Derived& final(){return *static_cast<Derived*>(this);}
|
||||
const Derived& final()const{return *static_cast<const Derived*>(this);}
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
bool operator==(
|
||||
const bidirectional_iter_adaptor_base<Derived,Base>& x,
|
||||
const bidirectional_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(
|
||||
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
|
||||
}
|
||||
|
||||
template<>
|
||||
struct iter_adaptor_selector<std::bidirectional_iterator_tag>
|
||||
{
|
||||
template<class Derived,class Base>
|
||||
using fn=bidirectional_iter_adaptor_base<Derived,Base>;
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
class random_access_iter_adaptor_base:
|
||||
public random_access_iterator_helper<
|
||||
Derived,
|
||||
typename Base::value_type,
|
||||
typename Base::difference_type,
|
||||
typename Base::pointer,
|
||||
typename Base::reference>
|
||||
{
|
||||
public:
|
||||
typedef typename Base::reference reference;
|
||||
typedef typename Base::difference_type difference_type;
|
||||
|
||||
reference operator*()const
|
||||
{
|
||||
return iter_adaptor_access::dereference(final());
|
||||
}
|
||||
|
||||
friend bool operator==(const Derived& x,const Derived& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(x,y);
|
||||
}
|
||||
|
||||
friend bool operator<(const Derived& x,const Derived& y)
|
||||
{
|
||||
return iter_adaptor_access::distance_to(x,y)>0;
|
||||
}
|
||||
|
||||
Derived& operator++()
|
||||
{
|
||||
iter_adaptor_access::increment(final());
|
||||
return final();
|
||||
}
|
||||
|
||||
Derived& operator--()
|
||||
{
|
||||
iter_adaptor_access::decrement(final());
|
||||
return final();
|
||||
}
|
||||
|
||||
Derived& operator+=(difference_type n)
|
||||
{
|
||||
iter_adaptor_access::advance(final(),n);
|
||||
return final();
|
||||
}
|
||||
|
||||
Derived& operator-=(difference_type n)
|
||||
{
|
||||
iter_adaptor_access::advance(final(),-n);
|
||||
return final();
|
||||
}
|
||||
|
||||
friend difference_type operator-(const Derived& x,const Derived& y)
|
||||
{
|
||||
return iter_adaptor_access::distance_to(y,x);
|
||||
}
|
||||
|
||||
private:
|
||||
Derived& final(){return *static_cast<Derived*>(this);}
|
||||
const Derived& final()const{return *static_cast<const Derived*>(this);}
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
bool operator==(
|
||||
const random_access_iter_adaptor_base<Derived,Base>& x,
|
||||
const random_access_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(
|
||||
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
|
||||
}
|
||||
|
||||
template<class Derived,class Base>
|
||||
bool operator<(
|
||||
const random_access_iter_adaptor_base<Derived,Base>& x,
|
||||
const random_access_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::distance_to(
|
||||
static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0;
|
||||
}
|
||||
|
||||
template<class Derived,class Base>
|
||||
typename random_access_iter_adaptor_base<Derived,Base>::difference_type
|
||||
operator-(
|
||||
const random_access_iter_adaptor_base<Derived,Base>& x,
|
||||
const random_access_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::distance_to(
|
||||
static_cast<const Derived&>(y),static_cast<const Derived&>(x));
|
||||
}
|
||||
|
||||
template<>
|
||||
struct iter_adaptor_selector<std::random_access_iterator_tag>
|
||||
{
|
||||
template<class Derived,class Base>
|
||||
using fn=random_access_iter_adaptor_base<Derived,Base>;
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
using iter_adaptor_base=mp11::mp_invoke_q<
|
||||
iter_adaptor_selector<typename Base::iterator_category>,
|
||||
Derived,Base
|
||||
>;
|
||||
|
||||
template<class Derived,class Base>
|
||||
class iter_adaptor:public iter_adaptor_base<Derived,Base>
|
||||
{
|
||||
protected:
|
||||
iter_adaptor(){}
|
||||
explicit iter_adaptor(const Base& b_):b(b_){}
|
||||
|
||||
const Base& base_reference()const{return b;}
|
||||
Base& base_reference(){return b;}
|
||||
|
||||
private:
|
||||
Base b;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
@@ -24,19 +24,19 @@ namespace detail{
|
||||
* with references to references, dealing with function pointers, etc.
|
||||
*/
|
||||
|
||||
template<typename Modifier,typename Value,typename KeyFromValue>
|
||||
template<typename Fun,typename Value,typename KeyFromValue>
|
||||
struct modify_key_adaptor
|
||||
{
|
||||
|
||||
modify_key_adaptor(Modifier mod_,KeyFromValue kfv_):mod(mod_),kfv(kfv_){}
|
||||
modify_key_adaptor(Fun f_,KeyFromValue kfv_):f(f_),kfv(kfv_){}
|
||||
|
||||
void operator()(Value& x)
|
||||
{
|
||||
mod(kfv(x));
|
||||
f(kfv(x));
|
||||
}
|
||||
|
||||
private:
|
||||
Modifier mod;
|
||||
Fun f;
|
||||
KeyFromValue kfv;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/* Copyright 2003-2025 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_MPL_TO_MP11_LIST_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_MPL_TO_MP11_LIST_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT)
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mp11/list.hpp>
|
||||
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/mpl/begin_end.hpp>
|
||||
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/mpl/deref.hpp>
|
||||
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/mpl/next.hpp>
|
||||
#include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename First,typename Last,typename... Ts>
|
||||
struct mpl_to_mp11_list_impl:mpl_to_mp11_list_impl<
|
||||
typename mpl::next<First>::type,Last,
|
||||
Ts...,typename mpl::deref<First>::type
|
||||
>{};
|
||||
|
||||
template<typename Last,typename... Ts>
|
||||
struct mpl_to_mp11_list_impl<Last,Last,Ts...>
|
||||
{
|
||||
using type=mp11::mp_list<Ts...>;
|
||||
};
|
||||
|
||||
template<typename TypeList>
|
||||
using mpl_to_mp11_list=typename mpl_to_mp11_list_impl<
|
||||
typename mpl::begin<TypeList>::type,
|
||||
typename boost::mpl::end<TypeList>::type
|
||||
>::type;
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
#endif
|
||||
#endif
|
||||