forked from boostorg/unordered
Compare commits
322 Commits
esp-idf-co
...
feature/fo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37168ad39a | ||
|
|
40ced996fd | ||
|
|
b5df79599e | ||
|
|
231f9785ff | ||
|
|
dd6e0439f9 | ||
|
|
00a9266096 | ||
|
|
f9b1a5f105 | ||
|
|
bb30498399 | ||
|
|
bfd11a70a0 | ||
|
|
3aff6ba0e6 | ||
|
|
b314cf1659 | ||
|
|
ac1de3c0af | ||
|
|
4190720406 | ||
|
|
07b452b4d4 | ||
|
|
bfde38c58b | ||
|
|
dfadb54df3 | ||
|
|
883789611c | ||
|
|
5e639a97a4 | ||
|
|
fb315252b3 | ||
|
|
d12ed06c3d | ||
|
|
49fc08b934 | ||
|
|
4f0edf9013 | ||
|
|
2afd1c5c9a | ||
|
|
492df9c9c6 | ||
|
|
e29bf7a4a0 | ||
|
|
7db310f6d2 | ||
|
|
1f781a407e | ||
|
|
ef54c6bd14 | ||
|
|
fb1b1dfe2d | ||
|
|
222f0a737d | ||
|
|
6c0d121e5b | ||
|
|
955dab4637 | ||
|
|
375d7157b6 | ||
|
|
01053738eb | ||
|
|
d8f226d429 | ||
|
|
627ffe4ed7 | ||
|
|
2adab2be61 | ||
|
|
e0b680ac29 | ||
|
|
ad1e3a49a5 | ||
|
|
1d15067ef2 | ||
|
|
8a3e5dd918 | ||
|
|
2aa62c63c1 | ||
|
|
c9d1b6009e | ||
|
|
1d553447a0 | ||
|
|
703f8d1065 | ||
|
|
fe32f153a2 | ||
|
|
59f4da0a47 | ||
|
|
99ad45ed77 | ||
|
|
d93875a65e | ||
|
|
c1d5902911 | ||
|
|
0ac4aeca50 | ||
|
|
776935f24d | ||
|
|
2f048ea6ac | ||
|
|
f3353c9be3 | ||
|
|
3d07c33efe | ||
|
|
8a1562cc78 | ||
|
|
4de1be8911 | ||
|
|
46065065be | ||
|
|
8e42367a62 | ||
|
|
d13a9dcaaf | ||
|
|
64cb43ce32 | ||
|
|
c9340390b0 | ||
|
|
c76f44a8b3 | ||
|
|
2290375515 | ||
|
|
a200af610f | ||
|
|
2cb1d2bdf0 | ||
|
|
ac2bc8d615 | ||
|
|
0d6ebb4d2f | ||
|
|
27c386d47b | ||
|
|
cf6f4023bb | ||
|
|
aa41ab4195 | ||
|
|
6e4e5ead03 | ||
|
|
eb5351b2c6 | ||
|
|
599dee204f | ||
|
|
6b1d2f13da | ||
|
|
b0f6bb128f | ||
|
|
0389e0bc16 | ||
|
|
9246c30178 | ||
|
|
bb6b57d1a4 | ||
|
|
4fa61b98eb | ||
|
|
5535faf3cc | ||
|
|
ec389cdecd | ||
|
|
7c5bad60c6 | ||
|
|
cc75360f4c | ||
|
|
3a0b752363 | ||
|
|
63eaed843f | ||
|
|
0b575dc983 | ||
|
|
b8d4df2b5c | ||
|
|
3bf28d7b61 | ||
|
|
acc7f0ce5c | ||
|
|
1532e301d1 | ||
|
|
e663812f24 | ||
|
|
9da61e9050 | ||
|
|
1de8801c08 | ||
|
|
e16537d244 | ||
|
|
14c190223c | ||
|
|
e3c91ad812 | ||
|
|
454cb24cc8 | ||
|
|
5e24f6ef22 | ||
|
|
d02d4094e6 | ||
|
|
9a03d1e904 | ||
|
|
3683b43242 | ||
|
|
fc5c8c3669 | ||
|
|
df32d79e8a | ||
|
|
aefb5dd66a | ||
|
|
f85e04ef31 | ||
|
|
8c58ffe546 | ||
|
|
d538f6184c | ||
|
|
7339f4264a | ||
|
|
87674d000b | ||
|
|
6227ae49a7 | ||
|
|
c39ed8a5cf | ||
|
|
d4f7939aae | ||
|
|
fc7b5573c1 | ||
|
|
1c14bc1215 | ||
|
|
4399e8b360 | ||
|
|
3f9bd00f01 | ||
|
|
05b3025c0e | ||
|
|
becd166e66 | ||
|
|
006f62047b | ||
|
|
334dcb91ac | ||
|
|
df7792040c | ||
|
|
57ea45cb8f | ||
|
|
4a8d687778 | ||
|
|
ccd40d0c44 | ||
|
|
35118b5a71 | ||
|
|
858737fd88 | ||
|
|
648fb7b99d | ||
|
|
59c84cb744 | ||
|
|
becd6078b3 | ||
|
|
e163aa465c | ||
|
|
3b1f635926 | ||
|
|
7abd7bb36d | ||
|
|
545ad4f7ad | ||
|
|
c42d86ac0d | ||
|
|
316eeea983 | ||
|
|
f2afbe9f85 | ||
|
|
e9a94cb62a | ||
|
|
91f5925c41 | ||
|
|
0bdfa3c39e | ||
|
|
09f0b7c0a8 | ||
|
|
72bca09429 | ||
|
|
58b78f8ff0 | ||
|
|
1ff2dc4042 | ||
|
|
05f9668597 | ||
|
|
c7836659d1 | ||
|
|
c4cc805063 | ||
|
|
9e2bf3681f | ||
|
|
77f265a678 | ||
|
|
6bda467942 | ||
|
|
1fa2e84774 | ||
|
|
7caab66011 | ||
|
|
69aff6f776 | ||
|
|
505a08cf95 | ||
|
|
f776ffa008 | ||
|
|
a4c38c02c8 | ||
|
|
889a81f034 | ||
|
|
ad96ea632e | ||
|
|
2955a966cf | ||
|
|
3fbaf21b8c | ||
|
|
32a7ed74e8 | ||
|
|
3913fce638 | ||
|
|
16f86b0770 | ||
|
|
2907083b73 | ||
|
|
1fa823d815 | ||
|
|
6e8e2112ba | ||
|
|
9560d10771 | ||
|
|
e543818e3e | ||
|
|
e0bb258b39 | ||
|
|
d3ef0b9a4f | ||
|
|
86d623a0f4 | ||
|
|
b964fa777c | ||
|
|
cde017f791 | ||
|
|
d1982a664b | ||
|
|
7e479d62dc | ||
|
|
6be32f3ba4 | ||
|
|
049a1ec8f6 | ||
|
|
b3754b10c8 | ||
|
|
7441be730e | ||
|
|
38f9cb750a | ||
|
|
8a9aab57c0 | ||
|
|
b61ec3a65a | ||
|
|
74c2ae627a | ||
|
|
74ca1e50f3 | ||
|
|
5fc929b829 | ||
|
|
3aaf895514 | ||
|
|
2057ccaeb5 | ||
|
|
dc7b8f3ff2 | ||
|
|
2b7e9d826d | ||
|
|
c57470e0d3 | ||
|
|
6b1379a992 | ||
|
|
f1eb5d2106 | ||
|
|
ad248ab76a | ||
|
|
f4888c7940 | ||
|
|
d02b12c9a1 | ||
|
|
2cf9d5ac4c | ||
|
|
f3803fc071 | ||
|
|
a3c6235f3a | ||
|
|
7501eefd87 | ||
|
|
2134116cbc | ||
|
|
b86143de46 | ||
|
|
7c8045aab5 | ||
|
|
c15bd0092d | ||
|
|
d233d83811 | ||
|
|
df0c375541 | ||
|
|
886b1b4ded | ||
|
|
48816135df | ||
|
|
4d0f698937 | ||
|
|
fdbc79d2a8 | ||
|
|
1a89b0aa14 | ||
|
|
8e9b7cf259 | ||
|
|
bf6643844b | ||
|
|
e9c3ed1531 | ||
|
|
7dfcdc6da8 | ||
|
|
9ad7096851 | ||
|
|
4cdfb2537a | ||
|
|
9280e13697 | ||
|
|
21872edf83 | ||
|
|
b7e021ffc6 | ||
|
|
e69bb3aece | ||
|
|
06512a00e1 | ||
|
|
bdfe294e61 | ||
|
|
ddb9f370af | ||
|
|
b0c0384401 | ||
|
|
bf6e381ff2 | ||
|
|
d5fcc77579 | ||
|
|
b0097982af | ||
|
|
2e3a8a0fc0 | ||
|
|
357eed44a1 | ||
|
|
2ae70cd05c | ||
|
|
d370ae1095 | ||
|
|
5c48ad9a79 | ||
|
|
621b5b4ec1 | ||
|
|
4dbc83ccbf | ||
|
|
398a64b5e0 | ||
|
|
b926dbbbe9 | ||
|
|
b244b33402 | ||
|
|
f2e4b25615 | ||
|
|
29f2f1db2c | ||
|
|
cec09e1c61 | ||
|
|
36a42116e8 | ||
|
|
d9dcaf8ba1 | ||
|
|
984cf13afd | ||
|
|
ac41bf6e86 | ||
|
|
5f21e3964e | ||
|
|
364cd86191 | ||
|
|
b1449ca502 | ||
|
|
6110a0827c | ||
|
|
71b64139da | ||
|
|
3582ac91d7 | ||
|
|
30997bd9ef | ||
|
|
cb673135d2 | ||
|
|
6ac1cf1a5f | ||
|
|
8f29a32a33 | ||
|
|
ac3520791e | ||
|
|
faa6e91ed2 | ||
|
|
86956b0be1 | ||
|
|
fdc39982f3 | ||
|
|
c37cfacb44 | ||
|
|
3af53a6598 | ||
|
|
19c500de27 | ||
|
|
855d538ea3 | ||
|
|
6b1ef16e38 | ||
|
|
1577da25cc | ||
|
|
c44695eb37 | ||
|
|
63fdf67568 | ||
|
|
80cb7281ba | ||
|
|
cefe5965be | ||
|
|
2a9f47ea2c | ||
|
|
85324f9a43 | ||
|
|
2e776ad155 | ||
|
|
f6544f69ca | ||
|
|
c61222403e | ||
|
|
c487f24611 | ||
|
|
8dcd40c8f3 | ||
|
|
0ea2cb5a7a | ||
|
|
5a4a2f3ffd | ||
|
|
5293b328b7 | ||
|
|
2889aab226 | ||
|
|
7a1a25991f | ||
|
|
43f8e5e933 | ||
|
|
f4940d9344 | ||
|
|
701cdff982 | ||
|
|
450c915284 | ||
|
|
892e437428 | ||
|
|
8905157c1e | ||
|
|
2eb57995dd | ||
|
|
b64b88eb65 | ||
|
|
3da4b6411c | ||
|
|
e115634812 | ||
|
|
fc0f354df4 | ||
|
|
ba5cbd5ca6 | ||
|
|
505b060637 | ||
|
|
12b9bd0a6d | ||
|
|
e8715ffb96 | ||
|
|
5d34b137a3 | ||
|
|
ad352a6703 | ||
|
|
7d69d18473 | ||
|
|
668abe4b0a | ||
|
|
5dcccfda3b | ||
|
|
56b271850a | ||
|
|
d338e94267 | ||
|
|
42abfe3c7d | ||
|
|
6ef6540378 | ||
|
|
9a9b8e0a7b | ||
|
|
5ad86f559f | ||
|
|
a8b0e19a33 | ||
|
|
2b61fbb8df | ||
|
|
dea6ce164c | ||
|
|
9ebb705e75 | ||
|
|
010dfa52e3 | ||
|
|
db9d9d1f77 | ||
|
|
6f342bf119 | ||
|
|
48765e82e0 | ||
|
|
f141cd1dea | ||
|
|
6258856d2b | ||
|
|
c93ea188f7 | ||
|
|
329eb419f5 | ||
|
|
e83c42ca26 | ||
|
|
f9eae4153f | ||
|
|
7b41f4783f | ||
|
|
7227cfc68a |
@@ -42,7 +42,12 @@ environment:
|
||||
|
||||
- FLAVOR: Visual Studio 2017
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 14,17,latest
|
||||
B2_CXXSTD: 14,17
|
||||
B2_TOOLSET: msvc-14.1
|
||||
|
||||
- FLAVOR: Visual Studio 2017
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: latest
|
||||
B2_TOOLSET: msvc-14.1
|
||||
|
||||
- FLAVOR: cygwin (32-bit)
|
||||
@@ -63,7 +68,7 @@ environment:
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 03,11
|
||||
B2_CXXSTD: 03
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
|
||||
@@ -71,21 +76,51 @@ environment:
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 14,1z
|
||||
B2_CXXSTD: 11
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
|
||||
- FLAVOR: cygwin (64-bit, latest)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
|
||||
- FLAVOR: cygwin (64-bit, latest)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 1z
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||
B2_CXXSTD: 03,11,14,17,2a
|
||||
B2_CXXSTD: 03,11,14
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||
B2_CXXSTD: 17,2a
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
|
||||
B2_CXXSTD: 03,11,14,17,2a
|
||||
B2_CXXSTD: 03,11,14
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
|
||||
B2_CXXSTD: 17,2a
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch
|
||||
commands:
|
||||
[
|
||||
'set -e',
|
||||
'uname -a',
|
||||
'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 []) +
|
||||
@@ -63,6 +64,7 @@ local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "c
|
||||
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
|
||||
commands:
|
||||
[
|
||||
'uname -a',
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
@@ -89,6 +91,7 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'echo $env:DRONE_STAGE_MACHINE',
|
||||
'cmd /C .drone\\\\drone.bat ' + library,
|
||||
]
|
||||
}
|
||||
@@ -168,8 +171,9 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 ASAN",
|
||||
"MacOS 12.4 Xcode 13.4.1 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey",
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
set -ex
|
||||
export PATH=~/.local/bin:/usr/local/bin:$PATH
|
||||
|
||||
DRONE_BUILD_DIR=$(pwd)
|
||||
|
||||
|
||||
@@ -1566,7 +1566,9 @@ Effects:;; Changes the container's maximum load factor, using `z` as a hint.
|
||||
void rehash(size_type n);
|
||||
```
|
||||
|
||||
Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
|
||||
Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container.
|
||||
|
||||
When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array.
|
||||
|
||||
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
|
||||
|
||||
@@ -1580,6 +1582,10 @@ Throws:;; The function has no effect if an exception is thrown, unless it is thr
|
||||
void reserve(size_type n);
|
||||
```
|
||||
|
||||
Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits<float>::infinity()`.
|
||||
|
||||
Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container.
|
||||
|
||||
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
|
||||
|
||||
[horizontal]
|
||||
|
||||
@@ -1345,7 +1345,9 @@ Effects:;; Changes the container's maximum load factor, using `z` as a hint.
|
||||
void rehash(size_type n);
|
||||
```
|
||||
|
||||
Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
|
||||
Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container.
|
||||
|
||||
When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array.
|
||||
|
||||
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
|
||||
|
||||
@@ -1359,6 +1361,10 @@ Throws:;; The function has no effect if an exception is thrown, unless it is thr
|
||||
void reserve(size_type n);
|
||||
```
|
||||
|
||||
Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits<float>::infinity()`.
|
||||
|
||||
Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container.
|
||||
|
||||
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
|
||||
|
||||
[horizontal]
|
||||
|
||||
@@ -1306,7 +1306,9 @@ Effects:;; Changes the container's maximum load factor, using `z` as a hint.
|
||||
void rehash(size_type n);
|
||||
```
|
||||
|
||||
Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
|
||||
Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container.
|
||||
|
||||
When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array.
|
||||
|
||||
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
|
||||
|
||||
@@ -1320,11 +1322,16 @@ Throws:;; The function has no effect if an exception is thrown, unless it is thr
|
||||
void reserve(size_type n);
|
||||
```
|
||||
|
||||
Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits<float>::infinity()`.
|
||||
|
||||
Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container.
|
||||
|
||||
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
|
||||
|
||||
[horizontal]
|
||||
Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function.
|
||||
|
||||
|
||||
---
|
||||
|
||||
=== Equality Comparisons
|
||||
|
||||
@@ -1329,7 +1329,9 @@ Effects:;; Changes the container's maximum load factor, using `z` as a hint.
|
||||
void rehash(size_type n);
|
||||
```
|
||||
|
||||
Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
|
||||
Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container.
|
||||
|
||||
When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array.
|
||||
|
||||
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
|
||||
|
||||
@@ -1343,11 +1345,16 @@ Throws:;; The function has no effect if an exception is thrown, unless it is thr
|
||||
void reserve(size_type n);
|
||||
```
|
||||
|
||||
Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits<float>::infinity()`.
|
||||
|
||||
Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container.
|
||||
|
||||
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
|
||||
|
||||
[horizontal]
|
||||
Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function.
|
||||
|
||||
|
||||
=== Equality Comparisons
|
||||
|
||||
==== operator==
|
||||
|
||||
@@ -494,11 +494,33 @@ namespace boost {
|
||||
group_pointer groups;
|
||||
|
||||
public:
|
||||
static std::size_t bucket_count_for(std::size_t num_buckets)
|
||||
{
|
||||
if (num_buckets == 0) {
|
||||
return 0;
|
||||
}
|
||||
return size_policy::size(size_policy::size_index(num_buckets));
|
||||
}
|
||||
|
||||
grouped_bucket_array()
|
||||
: empty_value<node_allocator_type>(
|
||||
empty_init_t(), node_allocator_type()),
|
||||
size_index_(0), size_(0), buckets(), groups()
|
||||
{
|
||||
}
|
||||
|
||||
grouped_bucket_array(size_type n, const Allocator& al)
|
||||
: empty_value<node_allocator_type>(empty_init_t(), al),
|
||||
size_index_(size_policy::size_index(n)),
|
||||
size_(size_policy::size(size_index_)), buckets(), groups()
|
||||
size_index_(0),
|
||||
size_(0), buckets(), groups()
|
||||
{
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_index_ = size_policy::size_index(n);
|
||||
size_ = size_policy::size(size_index_);
|
||||
|
||||
bucket_allocator_type bucket_alloc = this->get_bucket_allocator();
|
||||
group_allocator_type group_alloc = this->get_group_allocator();
|
||||
|
||||
@@ -646,7 +668,7 @@ namespace boost {
|
||||
|
||||
size_type bucket_count() const { return size_; }
|
||||
|
||||
iterator begin() const { return ++at(size_); }
|
||||
iterator begin() const { return size_ == 0 ? end() : ++at(size_); }
|
||||
|
||||
iterator end() const
|
||||
{
|
||||
@@ -660,6 +682,10 @@ namespace boost {
|
||||
|
||||
local_iterator begin(size_type n) const
|
||||
{
|
||||
if (size_ == 0) {
|
||||
return this->end(n);
|
||||
}
|
||||
|
||||
return local_iterator(
|
||||
(buckets + static_cast<difference_type>(n))->next);
|
||||
}
|
||||
@@ -670,12 +696,16 @@ namespace boost {
|
||||
|
||||
iterator at(size_type n) const
|
||||
{
|
||||
std::size_t const N = group::N;
|
||||
if (size_ > 0) {
|
||||
std::size_t const N = group::N;
|
||||
|
||||
iterator pbg(buckets + static_cast<difference_type>(n),
|
||||
groups + static_cast<difference_type>(n / N));
|
||||
iterator pbg(buckets + static_cast<difference_type>(n),
|
||||
groups + static_cast<difference_type>(n / N));
|
||||
|
||||
return pbg;
|
||||
return pbg;
|
||||
} else {
|
||||
return this->end();
|
||||
}
|
||||
}
|
||||
|
||||
span<Bucket> raw()
|
||||
|
||||
1843
include/boost/unordered/detail/foa.hpp
Normal file
1843
include/boost/unordered/detail/foa.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,7 @@
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/unordered/detail/fca.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
@@ -200,7 +201,7 @@ namespace boost {
|
||||
template <typename Types> struct table;
|
||||
|
||||
static const float minimum_max_load_factor = 1e-3f;
|
||||
static const std::size_t default_bucket_count = 11;
|
||||
static const std::size_t default_bucket_count = 0;
|
||||
|
||||
struct move_tag
|
||||
{
|
||||
@@ -618,39 +619,6 @@ namespace boost {
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Type checkers used for the transparent member functions added by C++20 and up
|
||||
|
||||
template <class, class = void> struct is_transparent : public false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_transparent<T,
|
||||
typename boost::make_void<typename T::is_transparent>::type>
|
||||
: public true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class, class A, class B> struct are_transparent
|
||||
{
|
||||
static bool const value =
|
||||
is_transparent<A>::value && is_transparent<B>::value;
|
||||
};
|
||||
|
||||
template <class Key, class UnorderedMap> struct transparent_non_iterable
|
||||
{
|
||||
typedef typename UnorderedMap::hasher hash;
|
||||
typedef typename UnorderedMap::key_equal key_equal;
|
||||
typedef typename UnorderedMap::iterator iterator;
|
||||
typedef typename UnorderedMap::const_iterator const_iterator;
|
||||
|
||||
static bool const value =
|
||||
are_transparent<Key, hash, key_equal>::value &&
|
||||
!boost::is_convertible<Key, iterator>::value &&
|
||||
!boost::is_convertible<Key, const_iterator>::value;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Explicitly call a destructor
|
||||
|
||||
@@ -2054,12 +2022,14 @@ namespace boost {
|
||||
|
||||
std::size_t bucket_size(std::size_t index) const
|
||||
{
|
||||
bucket_iterator itb = buckets_.at(index);
|
||||
node_pointer n = itb->next;
|
||||
std::size_t count = 0;
|
||||
while (n) {
|
||||
++count;
|
||||
n = n->next;
|
||||
if (size_ > 0) {
|
||||
bucket_iterator itb = buckets_.at(index);
|
||||
node_pointer n = itb->next;
|
||||
while (n) {
|
||||
++count;
|
||||
n = n->next;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -2069,13 +2039,18 @@ namespace boost {
|
||||
|
||||
void recalculate_max_load()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// From 6.3.1/13:
|
||||
// Only resize when size >= mlf_ * count
|
||||
max_load_ = boost::unordered::detail::double_to_size(
|
||||
floor(static_cast<double>(mlf_) *
|
||||
static_cast<double>(buckets_.bucket_count())));
|
||||
std::size_t const bc = buckets_.bucket_count();
|
||||
|
||||
// it's important we do the `bc == 0` check here because the `mlf_`
|
||||
// can be specified to be infinity. The operation `n * INF` is `INF`
|
||||
// for all `n > 0` but NaN for `n == 0`.
|
||||
//
|
||||
max_load_ =
|
||||
bc == 0 ? 0
|
||||
: boost::unordered::detail::double_to_size(
|
||||
static_cast<double>(mlf_) * static_cast<double>(bc));
|
||||
}
|
||||
|
||||
void max_load_factor(float z)
|
||||
@@ -2088,6 +2063,12 @@ namespace boost {
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Constructors
|
||||
|
||||
table()
|
||||
: functions(hasher(), key_equal()), size_(0), mlf_(1.0f),
|
||||
max_load_(0)
|
||||
{
|
||||
}
|
||||
|
||||
table(std::size_t num_buckets, hasher const& hf, key_equal const& eq,
|
||||
node_allocator_type const& a)
|
||||
: functions(hf, eq), size_(0), mlf_(1.0f), max_load_(0),
|
||||
@@ -2359,7 +2340,6 @@ namespace boost {
|
||||
template <typename UniqueType>
|
||||
void move_assign(table& x, UniqueType is_unique, false_type)
|
||||
{
|
||||
reserve(x.size_);
|
||||
if (node_alloc() == x.node_alloc()) {
|
||||
move_assign_equal_alloc(x);
|
||||
} else {
|
||||
@@ -2388,7 +2368,9 @@ namespace boost {
|
||||
{
|
||||
mlf_ = x.mlf_;
|
||||
recalculate_max_load();
|
||||
this->reserve_for_insert(x.size_);
|
||||
if (x.size_ > 0) {
|
||||
this->reserve_for_insert(x.size_);
|
||||
}
|
||||
this->clear_impl();
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
@@ -2420,11 +2402,14 @@ namespace boost {
|
||||
node_pointer find_node_impl(
|
||||
Key const& x, bucket_iterator itb) const
|
||||
{
|
||||
key_equal const& pred = this->key_eq();
|
||||
node_pointer p = itb->next;
|
||||
for (; p; p = p->next) {
|
||||
if (pred(x, extractor::extract(p->value()))) {
|
||||
break;
|
||||
node_pointer p = node_pointer();
|
||||
if (itb != buckets_.end()) {
|
||||
key_equal const& pred = this->key_eq();
|
||||
p = itb->next;
|
||||
for (; p; p = p->next) {
|
||||
if (pred(x, extractor::extract(p->value()))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return p;
|
||||
@@ -2453,11 +2438,13 @@ namespace boost {
|
||||
inline iterator transparent_find(
|
||||
Key const& k, Hash const& h, Pred const& pred) const
|
||||
{
|
||||
std::size_t const key_hash = h(k);
|
||||
bucket_iterator itb = buckets_.at(buckets_.position(key_hash));
|
||||
for (node_pointer p = itb->next; p; p = p->next) {
|
||||
if (BOOST_LIKELY(pred(k, extractor::extract(p->value())))) {
|
||||
return iterator(p, itb);
|
||||
if (size_ > 0) {
|
||||
std::size_t const key_hash = h(k);
|
||||
bucket_iterator itb = buckets_.at(buckets_.position(key_hash));
|
||||
for (node_pointer p = itb->next; p; p = p->next) {
|
||||
if (BOOST_LIKELY(pred(k, extractor::extract(p->value())))) {
|
||||
return iterator(p, itb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2467,11 +2454,13 @@ namespace boost {
|
||||
template <class Key>
|
||||
node_pointer* find_prev(Key const& key, bucket_iterator itb)
|
||||
{
|
||||
key_equal pred = this->key_eq();
|
||||
for (node_pointer* pp = boost::addressof(itb->next); *pp;
|
||||
pp = boost::addressof((*pp)->next)) {
|
||||
if (pred(key, extractor::extract((*pp)->value()))) {
|
||||
return pp;
|
||||
if (size_ > 0) {
|
||||
key_equal pred = this->key_eq();
|
||||
for (node_pointer* pp = boost::addressof(itb->next); *pp;
|
||||
pp = boost::addressof((*pp)->next)) {
|
||||
if (pred(key, extractor::extract((*pp)->value()))) {
|
||||
return pp;
|
||||
}
|
||||
}
|
||||
}
|
||||
typedef node_pointer* node_pointer_pointer;
|
||||
@@ -2503,6 +2492,17 @@ namespace boost {
|
||||
new_buckets.insert_node(itnewb, p);
|
||||
}
|
||||
|
||||
static std::size_t min_buckets(std::size_t num_elements, float mlf)
|
||||
{
|
||||
std::size_t num_buckets = static_cast<std::size_t>(
|
||||
std::ceil(static_cast<float>(num_elements) / mlf));
|
||||
|
||||
if (num_buckets == 0 && num_elements > 0) { // mlf == inf
|
||||
num_buckets = 1;
|
||||
}
|
||||
return num_buckets;
|
||||
}
|
||||
|
||||
void rehash(std::size_t);
|
||||
void reserve(std::size_t);
|
||||
void reserve_for_insert(std::size_t);
|
||||
@@ -3411,22 +3411,18 @@ namespace boost {
|
||||
template <typename Types>
|
||||
inline void table<Types>::rehash(std::size_t num_buckets)
|
||||
{
|
||||
std::size_t bc = (std::max)(num_buckets,
|
||||
static_cast<std::size_t>(1.0f + static_cast<float>(size_) / mlf_));
|
||||
num_buckets = (std::max)(
|
||||
min_buckets(size_, mlf_), buckets_.bucket_count_for(num_buckets));
|
||||
|
||||
if (bc <= buckets_.bucket_count()) {
|
||||
return;
|
||||
if (num_buckets != this->bucket_count()) {
|
||||
this->rehash_impl(num_buckets);
|
||||
}
|
||||
|
||||
this->rehash_impl(bc);
|
||||
}
|
||||
|
||||
template <class Types>
|
||||
inline void table<Types>::reserve(std::size_t num_elements)
|
||||
{
|
||||
std::size_t const num_buckets = static_cast<std::size_t>(
|
||||
std::ceil(static_cast<float>(num_elements) / mlf_));
|
||||
|
||||
std::size_t num_buckets = min_buckets(num_elements, mlf_);
|
||||
this->rehash(num_buckets);
|
||||
}
|
||||
|
||||
|
||||
59
include/boost/unordered/detail/type_traits.hpp
Normal file
59
include/boost/unordered/detail/type_traits.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
namespace detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Type checkers used for the transparent member functions added by C++20
|
||||
// and up
|
||||
|
||||
template <class, class = void>
|
||||
struct is_transparent : public boost::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_transparent<T,
|
||||
typename boost::make_void<typename T::is_transparent>::type>
|
||||
: public boost::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class, class A, class B> struct are_transparent
|
||||
{
|
||||
static bool const value =
|
||||
is_transparent<A>::value && is_transparent<B>::value;
|
||||
};
|
||||
|
||||
template <class Key, class UnorderedMap> struct transparent_non_iterable
|
||||
{
|
||||
typedef typename UnorderedMap::hasher hash;
|
||||
typedef typename UnorderedMap::key_equal key_equal;
|
||||
typedef typename UnorderedMap::iterator iterator;
|
||||
typedef typename UnorderedMap::const_iterator const_iterator;
|
||||
|
||||
static bool const value =
|
||||
are_transparent<Key, hash, key_equal>::value &&
|
||||
!boost::is_convertible<Key, iterator>::value &&
|
||||
!boost::is_convertible<Key, const_iterator>::value;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP
|
||||
75
include/boost/unordered/detail/xmx.hpp
Normal file
75
include/boost/unordered/detail/xmx.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 32b/64b xmx mix function.
|
||||
*
|
||||
* Copyright 2022 Peter Dimov.
|
||||
* Copyright 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 https://www.boost.org/libs/unordered for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_XMX_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_XMX_HPP
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
/* Bit mixer for improvement of statistical properties of hash functions.
|
||||
* The implementation is different on 64bit and 32bit architectures:
|
||||
*
|
||||
* - 64bit: same as xmx function in
|
||||
* http://jonkagstrom.com/bit-mixer-construction/index.html
|
||||
* - 32bit: generated by Hash Function Prospector
|
||||
* (https://github.com/skeeto/hash-prospector) and selected as the
|
||||
* best overall performer in benchmarks of Boost.Unordered flat containers.
|
||||
* Score assigned by Hash Prospector: 333.7934929677524
|
||||
*/
|
||||
|
||||
#if defined(SIZE_MAX)
|
||||
#if ((((SIZE_MAX >> 16) >> 16) >> 16) >> 15) != 0
|
||||
#define BOOST_UNORDERED_64B_ARCHITECTURE /* >64 bits assumed as 64 bits */
|
||||
#endif
|
||||
#elif defined(UINTPTR_MAX) /* used as proxy for std::size_t */
|
||||
#if ((((UINTPTR_MAX >> 16) >> 16) >> 16) >> 15) != 0
|
||||
#define BOOST_UNORDERED_64B_ARCHITECTURE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline std::size_t xmx(std::size_t x)noexcept
|
||||
{
|
||||
#if defined(BOOST_UNORDERED_64B_ARCHITECTURE)
|
||||
|
||||
boost::uint64_t z=(boost::uint64_t)x;
|
||||
|
||||
z^=z>>23;
|
||||
z*=0xff51afd7ed558ccdull;
|
||||
z^=z>>23;
|
||||
|
||||
return (std::size_t)z;
|
||||
|
||||
#else /* 32 bits assumed */
|
||||
|
||||
x^=x>>18;
|
||||
x*=0x56b5aaadu;
|
||||
x^=x>>16;
|
||||
|
||||
return x;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_64B_ARCHITECTURE
|
||||
#undef BOOST_UNORDERED_64B_ARCHITECTURE
|
||||
#endif
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace unordered */
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
44
include/boost/unordered/hash_traits.hpp
Normal file
44
include/boost/unordered/hash_traits.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Hash function characterization.
|
||||
*
|
||||
* Copyright 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 https://www.boost.org/libs/unordered for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UNORDERED_HASH_TRAITS_HPP
|
||||
#define BOOST_UNORDERED_HASH_TRAITS_HPP
|
||||
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename Hash,typename=void>
|
||||
struct hash_is_avalanching_impl:std::false_type{};
|
||||
|
||||
template<typename Hash>
|
||||
struct hash_is_avalanching_impl<Hash,void_t<typename Hash::is_avalanching>>:
|
||||
std::true_type{};
|
||||
|
||||
} /* namespace detail */
|
||||
|
||||
/* Each trait can be partially specialized by users for concrete hash functions
|
||||
* when actual characterization differs from default.
|
||||
*/
|
||||
|
||||
/* Derived from std::true_type if the type Hash::is_avalanching is present,
|
||||
* derived from std::false_type otherwise.
|
||||
*/
|
||||
template<typename Hash>
|
||||
struct hash_is_avalanching:detail::hash_is_avalanching_impl<Hash>::type{};
|
||||
|
||||
} /* namespace unordered */
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
619
include/boost/unordered/unordered_flat_map.hpp
Normal file
619
include/boost/unordered/unordered_flat_map.hpp
Normal file
@@ -0,0 +1,619 @@
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_UNORDERED_UNORDERED_FLAT_MAP_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_UNORDERED_FLAT_MAP_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/foa.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/unordered_flat_map_fwd.hpp>
|
||||
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */
|
||||
#endif
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
class unordered_flat_map
|
||||
{
|
||||
struct map_types
|
||||
{
|
||||
using key_type = Key;
|
||||
using raw_key_type = typename std::remove_const<Key>::type;
|
||||
using raw_mapped_type = typename std::remove_const<T>::type;
|
||||
|
||||
using init_type = std::pair<raw_key_type, raw_mapped_type>;
|
||||
using moved_type = std::pair<raw_key_type&&, raw_mapped_type&&>;
|
||||
using value_type = std::pair<Key const, T>;
|
||||
|
||||
template <class K, class V>
|
||||
static raw_key_type const& extract(std::pair<K, V> const& kv)
|
||||
{
|
||||
return kv.first;
|
||||
}
|
||||
|
||||
static moved_type move(value_type& x)
|
||||
{
|
||||
// TODO: we probably need to launder here
|
||||
return {std::move(const_cast<raw_key_type&>(x.first)),
|
||||
std::move(const_cast<raw_mapped_type&>(x.second))};
|
||||
}
|
||||
};
|
||||
|
||||
using table_type = detail::foa::table<map_types, Hash, KeyEqual,
|
||||
typename boost::allocator_rebind<Allocator,
|
||||
typename map_types::value_type>::type>;
|
||||
|
||||
table_type table_;
|
||||
|
||||
template <class K, class V, class H, class KE, class A, class Pred>
|
||||
typename unordered_flat_map<K, V, H, KE, A>::size_type friend erase_if(
|
||||
unordered_flat_map<K, V, H, KE, A>& set, Pred pred);
|
||||
|
||||
public:
|
||||
using key_type = Key;
|
||||
using mapped_type = T;
|
||||
using value_type = typename map_types::value_type;
|
||||
using init_type = typename map_types::init_type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using hasher = Hash;
|
||||
using key_equal = KeyEqual;
|
||||
using allocator_type = Allocator;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||
using const_pointer =
|
||||
typename boost::allocator_const_pointer<allocator_type>::type;
|
||||
using iterator = typename table_type::iterator;
|
||||
using const_iterator = typename table_type::const_iterator;
|
||||
|
||||
unordered_flat_map() : unordered_flat_map(0) {}
|
||||
|
||||
explicit unordered_flat_map(size_type n, hasher const& h = hasher(),
|
||||
key_equal const& pred = key_equal(),
|
||||
allocator_type const& a = allocator_type())
|
||||
: table_(n, h, pred, a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(size_type n, allocator_type const& a)
|
||||
: unordered_flat_map(n, hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(size_type n, hasher const& h, allocator_type const& a)
|
||||
: unordered_flat_map(n, h, key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
explicit unordered_flat_map(allocator_type const& a)
|
||||
: unordered_flat_map(0, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
unordered_flat_map(Iterator first, Iterator last, size_type n = 0,
|
||||
hasher const& h = hasher(), key_equal const& pred = key_equal(),
|
||||
allocator_type const& a = allocator_type())
|
||||
: unordered_flat_map(n, h, pred, a)
|
||||
{
|
||||
this->insert(first, last);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
unordered_flat_map(
|
||||
Iterator first, Iterator last, size_type n, allocator_type const& a)
|
||||
: unordered_flat_map(first, last, n, hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
unordered_flat_map(Iterator first, Iterator last, size_type n,
|
||||
hasher const& h, allocator_type const& a)
|
||||
: unordered_flat_map(first, last, n, h, key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(unordered_flat_map const& other) : table_(other.table_)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(
|
||||
unordered_flat_map const& other, allocator_type const& a)
|
||||
: table_(other.table_, a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(unordered_flat_map&& other)
|
||||
noexcept(std::is_nothrow_move_constructible<hasher>::value&&
|
||||
std::is_nothrow_move_constructible<key_equal>::value&&
|
||||
std::is_nothrow_move_constructible<allocator_type>::value)
|
||||
: table_(std::move(other.table_))
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(unordered_flat_map&& other, allocator_type const& al)
|
||||
: table_(std::move(other.table_), al)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(std::initializer_list<value_type> ilist,
|
||||
size_type n = 0, hasher const& h = hasher(),
|
||||
key_equal const& pred = key_equal(),
|
||||
allocator_type const& a = allocator_type())
|
||||
: unordered_flat_map(ilist.begin(), ilist.end(), n, h, pred, a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(std::initializer_list<value_type> init, size_type n,
|
||||
allocator_type const& a)
|
||||
: unordered_flat_map(init, n, hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_map(std::initializer_list<value_type> init, size_type n,
|
||||
hasher const& h, allocator_type const& a)
|
||||
: unordered_flat_map(init, n, h, key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
~unordered_flat_map() = default;
|
||||
|
||||
unordered_flat_map& operator=(unordered_flat_map const& other)
|
||||
{
|
||||
table_ = other.table_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_flat_map& operator=(unordered_flat_map&& other) noexcept(
|
||||
noexcept(std::declval<table_type&>() = std::declval<table_type&&>()))
|
||||
{
|
||||
table_ = std::move(other.table_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
allocator_type get_allocator() const noexcept
|
||||
{
|
||||
return table_.get_allocator();
|
||||
}
|
||||
|
||||
/// Iterators
|
||||
///
|
||||
|
||||
iterator begin() noexcept { return table_.begin(); }
|
||||
const_iterator begin() const noexcept { return table_.begin(); }
|
||||
const_iterator cbegin() const noexcept { return table_.cbegin(); }
|
||||
|
||||
iterator end() noexcept { return table_.end(); }
|
||||
const_iterator end() const noexcept { return table_.end(); }
|
||||
const_iterator cend() const noexcept { return table_.cend(); }
|
||||
|
||||
/// Capacity
|
||||
///
|
||||
|
||||
BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept
|
||||
{
|
||||
return table_.empty();
|
||||
}
|
||||
|
||||
size_type size() const noexcept { return table_.size(); }
|
||||
|
||||
size_type max_size() const noexcept { return table_.max_size(); }
|
||||
|
||||
/// Modifiers
|
||||
///
|
||||
|
||||
void clear() noexcept { table_.clear(); }
|
||||
|
||||
template <class Ty>
|
||||
BOOST_FORCEINLINE auto insert(Ty&& value)
|
||||
-> decltype(table_.insert(std::forward<Ty>(value)))
|
||||
{
|
||||
return table_.insert(std::forward<Ty>(value));
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE std::pair<iterator, bool> insert(init_type&& value)
|
||||
{
|
||||
return table_.insert(std::move(value));
|
||||
}
|
||||
|
||||
template <class Ty>
|
||||
BOOST_FORCEINLINE auto insert(const_iterator, Ty&& value)
|
||||
-> decltype(table_.insert(std::forward<Ty>(value)).first)
|
||||
{
|
||||
return table_.insert(std::forward<Ty>(value)).first;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE iterator insert(const_iterator, init_type&& value)
|
||||
{
|
||||
return table_.insert(std::move(value)).first;
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
BOOST_FORCEINLINE void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
for (auto pos = first; pos != last; ++pos) {
|
||||
table_.emplace(*pos);
|
||||
}
|
||||
}
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist)
|
||||
{
|
||||
this->insert(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template <class M>
|
||||
std::pair<iterator, bool> insert_or_assign(key_type const& key, M&& obj)
|
||||
{
|
||||
auto iter_bool_pair = table_.try_emplace(key, std::forward<M>(obj));
|
||||
if (iter_bool_pair.second) {
|
||||
return iter_bool_pair;
|
||||
}
|
||||
iter_bool_pair.first->second = std::forward<M>(obj);
|
||||
return iter_bool_pair;
|
||||
}
|
||||
|
||||
template <class M>
|
||||
std::pair<iterator, bool> insert_or_assign(key_type&& key, M&& obj)
|
||||
{
|
||||
auto iter_bool_pair =
|
||||
table_.try_emplace(std::move(key), std::forward<M>(obj));
|
||||
if (iter_bool_pair.second) {
|
||||
return iter_bool_pair;
|
||||
}
|
||||
iter_bool_pair.first->second = std::forward<M>(obj);
|
||||
return iter_bool_pair;
|
||||
}
|
||||
|
||||
template <class M>
|
||||
iterator insert_or_assign(const_iterator, key_type const& key, M&& obj)
|
||||
{
|
||||
return this->insert_or_assign(key, std::forward<M>(obj)).first;
|
||||
}
|
||||
|
||||
template <class M>
|
||||
iterator insert_or_assign(const_iterator, key_type&& key, M&& obj)
|
||||
{
|
||||
return this->insert_or_assign(std::move(key), std::forward<M>(obj))
|
||||
.first;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
BOOST_FORCEINLINE std::pair<iterator, bool> emplace(Args&&... args)
|
||||
{
|
||||
return table_.emplace(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
BOOST_FORCEINLINE iterator emplace_hint(const_iterator, Args&&... args)
|
||||
{
|
||||
return table_.emplace(std::forward<Args>(args)...).first;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
BOOST_FORCEINLINE std::pair<iterator, bool> try_emplace(
|
||||
key_type const& key, Args&&... args)
|
||||
{
|
||||
return table_.try_emplace(key, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
BOOST_FORCEINLINE std::pair<iterator, bool> try_emplace(
|
||||
key_type&& key, Args&&... args)
|
||||
{
|
||||
return table_.try_emplace(std::move(key), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
BOOST_FORCEINLINE iterator try_emplace(
|
||||
const_iterator, key_type const& key, Args&&... args)
|
||||
{
|
||||
return table_.try_emplace(key, std::forward<Args>(args)...).first;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
BOOST_FORCEINLINE iterator try_emplace(
|
||||
const_iterator, key_type&& key, Args&&... args)
|
||||
{
|
||||
return table_.try_emplace(std::move(key), std::forward<Args>(args)...)
|
||||
.first;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void erase(iterator pos) { table_.erase(pos); }
|
||||
BOOST_FORCEINLINE void erase(const_iterator pos)
|
||||
{
|
||||
return table_.erase(pos);
|
||||
}
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
while (first != last) {
|
||||
this->erase(first++);
|
||||
}
|
||||
return iterator{detail::foa::const_iterator_cast_tag{}, last};
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE size_type erase(key_type const& key)
|
||||
{
|
||||
return table_.erase(key);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
BOOST_FORCEINLINE typename std::enable_if<
|
||||
detail::transparent_non_iterable<K, unordered_flat_map>::value,
|
||||
size_type>::type
|
||||
erase(K const& key)
|
||||
{
|
||||
return table_.erase(key);
|
||||
}
|
||||
|
||||
void swap(unordered_flat_map& rhs) noexcept(
|
||||
noexcept(std::declval<table_type&>().swap(std::declval<table_type&>())))
|
||||
{
|
||||
table_.swap(rhs.table_);
|
||||
}
|
||||
|
||||
template <class H2, class P2>
|
||||
void merge(
|
||||
unordered_flat_map<key_type, mapped_type, H2, P2, allocator_type>&
|
||||
source)
|
||||
{
|
||||
table_.merge(source.table_);
|
||||
}
|
||||
|
||||
template <class H2, class P2>
|
||||
void merge(
|
||||
unordered_flat_map<key_type, mapped_type, H2, P2, allocator_type>&&
|
||||
source)
|
||||
{
|
||||
table_.merge(std::move(source.table_));
|
||||
}
|
||||
|
||||
/// Lookup
|
||||
///
|
||||
|
||||
mapped_type& at(key_type const& key)
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos != table_.end()) {
|
||||
return pos->second;
|
||||
}
|
||||
// TODO: someday refactor this to conditionally serialize the key and
|
||||
// include it in the error message
|
||||
//
|
||||
boost::throw_exception(
|
||||
std::out_of_range("key was not found in unordered_flat_map"));
|
||||
}
|
||||
|
||||
mapped_type const& at(key_type const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos != table_.end()) {
|
||||
return pos->second;
|
||||
}
|
||||
boost::throw_exception(
|
||||
std::out_of_range("key was not found in unordered_flat_map"));
|
||||
}
|
||||
|
||||
mapped_type& operator[](key_type const& key)
|
||||
{
|
||||
return table_.try_emplace(key).first->second;
|
||||
}
|
||||
|
||||
mapped_type& operator[](key_type&& key)
|
||||
{
|
||||
return table_.try_emplace(std::move(key)).first->second;
|
||||
}
|
||||
|
||||
size_type count(key_type const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
return pos != table_.end() ? 1 : 0;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename std::enable_if<
|
||||
detail::are_transparent<K, hasher, key_equal>::value, size_type>::type
|
||||
count(K const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
return pos != table_.end() ? 1 : 0;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE iterator find(key_type const& key)
|
||||
{
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE const_iterator find(key_type const& key) const
|
||||
{
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
BOOST_FORCEINLINE typename std::enable_if<
|
||||
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||
iterator>::type
|
||||
find(K const& key)
|
||||
{
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
BOOST_FORCEINLINE typename std::enable_if<
|
||||
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||
const_iterator>::type
|
||||
find(K const& key) const
|
||||
{
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
bool contains(key_type const& key) const
|
||||
{
|
||||
return this->find(key) != this->end();
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename std::enable_if<
|
||||
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||
bool>::type
|
||||
contains(K const& key) const
|
||||
{
|
||||
return this->find(key) != this->end();
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator> equal_range(key_type const& key)
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos == table_.end()) {
|
||||
return {pos, pos};
|
||||
}
|
||||
|
||||
auto next = pos;
|
||||
++next;
|
||||
return {pos, next};
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(
|
||||
key_type const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos == table_.end()) {
|
||||
return {pos, pos};
|
||||
}
|
||||
|
||||
auto next = pos;
|
||||
++next;
|
||||
return {pos, next};
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename std::enable_if<
|
||||
detail::are_transparent<K, hasher, key_equal>::value,
|
||||
std::pair<iterator, iterator> >::type
|
||||
equal_range(K const& key)
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos == table_.end()) {
|
||||
return {pos, pos};
|
||||
}
|
||||
|
||||
auto next = pos;
|
||||
++next;
|
||||
return {pos, next};
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename std::enable_if<
|
||||
detail::are_transparent<K, hasher, key_equal>::value,
|
||||
std::pair<const_iterator, const_iterator> >::type
|
||||
equal_range(K const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos == table_.end()) {
|
||||
return {pos, pos};
|
||||
}
|
||||
|
||||
auto next = pos;
|
||||
++next;
|
||||
return {pos, next};
|
||||
}
|
||||
|
||||
/// Hash Policy
|
||||
///
|
||||
|
||||
size_type bucket_count() const noexcept { return table_.capacity(); }
|
||||
|
||||
float load_factor() const noexcept { return table_.load_factor(); }
|
||||
|
||||
float max_load_factor() const noexcept
|
||||
{
|
||||
return table_.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float) {}
|
||||
|
||||
void rehash(size_type n) { table_.rehash(n); }
|
||||
|
||||
void reserve(size_type n) { table_.reserve(n); }
|
||||
|
||||
/// Observers
|
||||
///
|
||||
|
||||
hasher hash_function() const { return table_.hash_function(); }
|
||||
|
||||
key_equal key_eq() const { return table_.key_eq(); }
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
bool operator==(
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
||||
{
|
||||
if (&lhs == &rhs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (lhs.size() == rhs.size()) && ([&] {
|
||||
for (auto const& kvp : lhs) {
|
||||
auto pos = rhs.find(kvp.first);
|
||||
if ((pos == rhs.end()) || (*pos != kvp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})();
|
||||
}
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
bool operator!=(
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
void swap(unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& rhs)
|
||||
noexcept(noexcept(lhs.swap(rhs)))
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator,
|
||||
class Pred>
|
||||
typename unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>::size_type
|
||||
erase_if(
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& map, Pred pred)
|
||||
{
|
||||
return erase_if(map.table_, pred);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4714 */
|
||||
#endif
|
||||
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
49
include/boost/unordered/unordered_flat_map_fwd.hpp
Normal file
49
include/boost/unordered/unordered_flat_map_fwd.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_UNORDERED_FLAT_MAP_FWD_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_FLAT_MAP_FWD_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
class KeyEqual = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
class unordered_flat_map;
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
bool operator==(
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs);
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
bool operator!=(
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs);
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
void swap(unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& rhs)
|
||||
noexcept(noexcept(lhs.swap(rhs)));
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_flat_map;
|
||||
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::operator==;
|
||||
using boost::unordered::operator!=;
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
494
include/boost/unordered/unordered_flat_set.hpp
Normal file
494
include/boost/unordered/unordered_flat_set.hpp
Normal file
@@ -0,0 +1,494 @@
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_UNORDERED_UNORDERED_FLAT_SET_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_UNORDERED_FLAT_SET_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/foa.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/unordered_flat_set_fwd.hpp>
|
||||
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */
|
||||
#endif
|
||||
|
||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||
class unordered_flat_set
|
||||
{
|
||||
struct set_types
|
||||
{
|
||||
using key_type = Key;
|
||||
using init_type = Key;
|
||||
using value_type = Key;
|
||||
static Key const& extract(value_type const& key) { return key; }
|
||||
static Key&& move(value_type& x) { return std::move(x); }
|
||||
};
|
||||
|
||||
using table_type = detail::foa::table<set_types, Hash, KeyEqual,
|
||||
typename boost::allocator_rebind<Allocator,
|
||||
typename set_types::value_type>::type>;
|
||||
|
||||
table_type table_;
|
||||
|
||||
template <class K, class H, class KE, class A, class Pred>
|
||||
typename unordered_flat_set<K, H, KE, A>::size_type friend erase_if(
|
||||
unordered_flat_set<K, H, KE, A>& set, Pred pred);
|
||||
|
||||
public:
|
||||
using key_type = Key;
|
||||
using value_type = typename set_types::value_type;
|
||||
using init_type = typename set_types::init_type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using hasher = Hash;
|
||||
using key_equal = KeyEqual;
|
||||
using allocator_type = Allocator;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||
using const_pointer =
|
||||
typename boost::allocator_const_pointer<allocator_type>::type;
|
||||
using iterator = typename table_type::iterator;
|
||||
using const_iterator = typename table_type::const_iterator;
|
||||
|
||||
unordered_flat_set() : unordered_flat_set(0) {}
|
||||
|
||||
explicit unordered_flat_set(size_type n, hasher const& h = hasher(),
|
||||
key_equal const& pred = key_equal(),
|
||||
allocator_type const& a = allocator_type())
|
||||
: table_(n, h, pred, a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(size_type n, allocator_type const& a)
|
||||
: unordered_flat_set(n, hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(size_type n, hasher const& h, allocator_type const& a)
|
||||
: unordered_flat_set(n, h, key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
explicit unordered_flat_set(allocator_type const& a)
|
||||
: unordered_flat_set(0, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
unordered_flat_set(Iterator first, Iterator last, size_type n = 0,
|
||||
hasher const& h = hasher(), key_equal const& pred = key_equal(),
|
||||
allocator_type const& a = allocator_type())
|
||||
: unordered_flat_set(n, h, pred, a)
|
||||
{
|
||||
this->insert(first, last);
|
||||
}
|
||||
|
||||
template <class InputIt>
|
||||
unordered_flat_set(
|
||||
InputIt first, InputIt last, size_type n, allocator_type const& a)
|
||||
: unordered_flat_set(first, last, n, hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
unordered_flat_set(Iterator first, Iterator last, size_type n,
|
||||
hasher const& h, allocator_type const& a)
|
||||
: unordered_flat_set(first, last, n, h, key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(unordered_flat_set const& other) : table_(other.table_)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(
|
||||
unordered_flat_set const& other, allocator_type const& a)
|
||||
: table_(other.table_, a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(unordered_flat_set&& other)
|
||||
noexcept(std::is_nothrow_move_constructible<hasher>::value&&
|
||||
std::is_nothrow_move_constructible<key_equal>::value&&
|
||||
std::is_nothrow_move_constructible<allocator_type>::value)
|
||||
: table_(std::move(other.table_))
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(unordered_flat_set&& other, allocator_type const& al)
|
||||
: table_(std::move(other.table_), al)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(std::initializer_list<value_type> ilist,
|
||||
size_type n = 0, hasher const& h = hasher(),
|
||||
key_equal const& pred = key_equal(),
|
||||
allocator_type const& a = allocator_type())
|
||||
: unordered_flat_set(ilist.begin(), ilist.end(), n, h, pred, a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(std::initializer_list<value_type> init, size_type n,
|
||||
allocator_type const& a)
|
||||
: unordered_flat_set(init, n, hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_flat_set(std::initializer_list<value_type> init, size_type n,
|
||||
hasher const& h, allocator_type const& a)
|
||||
: unordered_flat_set(init, n, h, key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
~unordered_flat_set() = default;
|
||||
|
||||
unordered_flat_set& operator=(unordered_flat_set const& other)
|
||||
{
|
||||
table_ = other.table_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_flat_set& operator=(unordered_flat_set&& other) noexcept(
|
||||
noexcept(std::declval<table_type&>() = std::declval<table_type&&>()))
|
||||
{
|
||||
table_ = std::move(other.table_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
allocator_type get_allocator() const noexcept
|
||||
{
|
||||
return table_.get_allocator();
|
||||
}
|
||||
|
||||
/// Iterators
|
||||
///
|
||||
|
||||
iterator begin() noexcept { return table_.begin(); }
|
||||
const_iterator begin() const noexcept { return table_.begin(); }
|
||||
const_iterator cbegin() const noexcept { return table_.cbegin(); }
|
||||
|
||||
iterator end() noexcept { return table_.end(); }
|
||||
const_iterator end() const noexcept { return table_.end(); }
|
||||
const_iterator cend() const noexcept { return table_.cend(); }
|
||||
|
||||
/// Capacity
|
||||
///
|
||||
|
||||
BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept
|
||||
{
|
||||
return table_.empty();
|
||||
}
|
||||
|
||||
size_type size() const noexcept { return table_.size(); }
|
||||
|
||||
size_type max_size() const noexcept { return table_.max_size(); }
|
||||
|
||||
/// Modifiers
|
||||
///
|
||||
|
||||
void clear() noexcept { table_.clear(); }
|
||||
|
||||
BOOST_FORCEINLINE std::pair<iterator, bool> insert(
|
||||
value_type const& value)
|
||||
{
|
||||
return table_.insert(value);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE std::pair<iterator, bool> insert(value_type&& value)
|
||||
{
|
||||
return table_.insert(std::move(value));
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE iterator insert(const_iterator, value_type const& value)
|
||||
{
|
||||
return table_.insert(value).first;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE iterator insert(const_iterator, value_type&& value)
|
||||
{
|
||||
return table_.insert(std::move(value)).first;
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
for (auto pos = first; pos != last; ++pos) {
|
||||
table_.emplace(*pos);
|
||||
}
|
||||
}
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist)
|
||||
{
|
||||
this->insert(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
BOOST_FORCEINLINE std::pair<iterator, bool> emplace(Args&&... args)
|
||||
{
|
||||
return table_.emplace(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
BOOST_FORCEINLINE iterator emplace_hint(const_iterator, Args&&... args)
|
||||
{
|
||||
return table_.emplace(std::forward<Args>(args)...).first;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void erase(const_iterator pos)
|
||||
{
|
||||
return table_.erase(pos);
|
||||
}
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
while (first != last) {
|
||||
this->erase(first++);
|
||||
}
|
||||
return iterator{detail::foa::const_iterator_cast_tag{}, last};
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE size_type erase(key_type const& key)
|
||||
{
|
||||
return table_.erase(key);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
BOOST_FORCEINLINE typename std::enable_if<
|
||||
detail::transparent_non_iterable<K, unordered_flat_set>::value,
|
||||
size_type>::type
|
||||
erase(K const& key)
|
||||
{
|
||||
return table_.erase(key);
|
||||
}
|
||||
|
||||
void swap(unordered_flat_set& rhs) noexcept(
|
||||
noexcept(std::declval<table_type&>().swap(std::declval<table_type&>())))
|
||||
{
|
||||
table_.swap(rhs.table_);
|
||||
}
|
||||
|
||||
template <class H2, class P2>
|
||||
void merge(unordered_flat_set<key_type, H2, P2, allocator_type>& source)
|
||||
{
|
||||
table_.merge(source.table_);
|
||||
}
|
||||
|
||||
template <class H2, class P2>
|
||||
void merge(unordered_flat_set<key_type, H2, P2, allocator_type>&& source)
|
||||
{
|
||||
table_.merge(std::move(source.table_));
|
||||
}
|
||||
|
||||
/// Lookup
|
||||
///
|
||||
|
||||
size_type count(key_type const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
return pos != table_.end() ? 1 : 0;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename std::enable_if<
|
||||
detail::are_transparent<K, hasher, key_equal>::value, size_type>::type
|
||||
count(K const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
return pos != table_.end() ? 1 : 0;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE iterator find(key_type const& key)
|
||||
{
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE const_iterator find(key_type const& key) const
|
||||
{
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
BOOST_FORCEINLINE typename std::enable_if<
|
||||
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||
iterator>::type
|
||||
find(K const& key)
|
||||
{
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
BOOST_FORCEINLINE typename std::enable_if<
|
||||
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||
const_iterator>::type
|
||||
find(K const& key) const
|
||||
{
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
bool contains(key_type const& key) const
|
||||
{
|
||||
return this->find(key) != this->end();
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename std::enable_if<
|
||||
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||
bool>::type
|
||||
contains(K const& key) const
|
||||
{
|
||||
return this->find(key) != this->end();
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator> equal_range(key_type const& key)
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos == table_.end()) {
|
||||
return {pos, pos};
|
||||
}
|
||||
|
||||
auto next = pos;
|
||||
++next;
|
||||
return {pos, next};
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(
|
||||
key_type const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos == table_.end()) {
|
||||
return {pos, pos};
|
||||
}
|
||||
|
||||
auto next = pos;
|
||||
++next;
|
||||
return {pos, next};
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename std::enable_if<
|
||||
detail::are_transparent<K, hasher, key_equal>::value,
|
||||
std::pair<iterator, iterator> >::type
|
||||
equal_range(K const& key)
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos == table_.end()) {
|
||||
return {pos, pos};
|
||||
}
|
||||
|
||||
auto next = pos;
|
||||
++next;
|
||||
return {pos, next};
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename std::enable_if<
|
||||
detail::are_transparent<K, hasher, key_equal>::value,
|
||||
std::pair<const_iterator, const_iterator> >::type
|
||||
equal_range(K const& key) const
|
||||
{
|
||||
auto pos = table_.find(key);
|
||||
if (pos == table_.end()) {
|
||||
return {pos, pos};
|
||||
}
|
||||
|
||||
auto next = pos;
|
||||
++next;
|
||||
return {pos, next};
|
||||
}
|
||||
|
||||
/// Hash Policy
|
||||
///
|
||||
|
||||
size_type bucket_count() const noexcept { return table_.capacity(); }
|
||||
|
||||
float load_factor() const noexcept { return table_.load_factor(); }
|
||||
|
||||
float max_load_factor() const noexcept
|
||||
{
|
||||
return table_.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float) {}
|
||||
|
||||
void rehash(size_type n) { table_.rehash(n); }
|
||||
|
||||
void reserve(size_type n) { table_.reserve(n); }
|
||||
|
||||
/// Observers
|
||||
///
|
||||
|
||||
hasher hash_function() const { return table_.hash_function(); }
|
||||
|
||||
key_equal key_eq() const { return table_.key_eq(); }
|
||||
};
|
||||
|
||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||
bool operator==(
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||
{
|
||||
if (&lhs == &rhs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (lhs.size() == rhs.size()) && ([&] {
|
||||
for (auto const& key : lhs) {
|
||||
auto pos = rhs.find(key);
|
||||
if ((pos == rhs.end()) || (key != *pos)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})();
|
||||
}
|
||||
|
||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||
bool operator!=(
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||
void swap(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator>& rhs)
|
||||
noexcept(noexcept(lhs.swap(rhs)))
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
template <class Key, class Hash, class KeyEqual, class Allocator,
|
||||
class Pred>
|
||||
typename unordered_flat_set<Key, Hash, KeyEqual, Allocator>::size_type
|
||||
erase_if(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& set, Pred pred)
|
||||
{
|
||||
return erase_if(set.table_, pred);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4714 */
|
||||
#endif
|
||||
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
49
include/boost/unordered/unordered_flat_set_fwd.hpp
Normal file
49
include/boost/unordered/unordered_flat_set_fwd.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_UNORDERED_FLAT_SET_FWD_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_FLAT_SET_FWD_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class Key, class Hash = boost::hash<Key>,
|
||||
class KeyEqual = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<Key> >
|
||||
class unordered_flat_set;
|
||||
|
||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||
bool operator==(
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs);
|
||||
|
||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||
bool operator!=(
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs);
|
||||
|
||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||
void swap(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator>& rhs)
|
||||
noexcept(noexcept(lhs.swap(rhs)));
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_flat_set;
|
||||
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::operator==;
|
||||
using boost::unordered::operator!=;
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -1664,8 +1664,6 @@ namespace boost {
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
unordered_map<K, T, H, P, A>::unordered_map()
|
||||
: table_(boost::unordered::detail::default_bucket_count, hasher(),
|
||||
key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2069,6 +2067,10 @@ namespace boost {
|
||||
template <class K, class T, class H, class P, class A>
|
||||
float unordered_map<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
|
||||
{
|
||||
if (table_.size_ == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(table_.bucket_count() != 0);
|
||||
return static_cast<float>(table_.size_) /
|
||||
static_cast<float>(table_.bucket_count());
|
||||
@@ -2143,8 +2145,6 @@ namespace boost {
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
unordered_multimap<K, T, H, P, A>::unordered_multimap()
|
||||
: table_(boost::unordered::detail::default_bucket_count, hasher(),
|
||||
key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2506,6 +2506,10 @@ namespace boost {
|
||||
template <class K, class T, class H, class P, class A>
|
||||
float unordered_multimap<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
|
||||
{
|
||||
if (table_.size_ == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(table_.bucket_count() != 0);
|
||||
return static_cast<float>(table_.size_) /
|
||||
static_cast<float>(table_.bucket_count());
|
||||
|
||||
@@ -1266,8 +1266,6 @@ namespace boost {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
template <class T, class H, class P, class A>
|
||||
unordered_set<T, H, P, A>::unordered_set()
|
||||
: table_(boost::unordered::detail::default_bucket_count, hasher(),
|
||||
key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1586,6 +1584,10 @@ namespace boost {
|
||||
template <class T, class H, class P, class A>
|
||||
float unordered_set<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
|
||||
{
|
||||
if (table_.size_ == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(table_.bucket_count() != 0);
|
||||
return static_cast<float>(table_.size_) /
|
||||
static_cast<float>(table_.bucket_count());
|
||||
@@ -1660,8 +1662,6 @@ namespace boost {
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
unordered_multiset<T, H, P, A>::unordered_multiset()
|
||||
: table_(boost::unordered::detail::default_bucket_count, hasher(),
|
||||
key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1986,6 +1986,10 @@ namespace boost {
|
||||
template <class T, class H, class P, class A>
|
||||
float unordered_multiset<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
|
||||
{
|
||||
if (table_.size_ == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(table_.bucket_count() != 0);
|
||||
return static_cast<float>(table_.size_) /
|
||||
static_cast<float>(table_.bucket_count());
|
||||
|
||||
@@ -47,6 +47,7 @@ run unordered/equivalent_keys_tests.cpp ;
|
||||
run unordered/constructor_tests.cpp ;
|
||||
run unordered/copy_tests.cpp ;
|
||||
run unordered/move_tests.cpp ;
|
||||
run unordered/post_move_tests.cpp ;
|
||||
run unordered/assign_tests.cpp ;
|
||||
run unordered/insert_tests.cpp ;
|
||||
run unordered/insert_stable_tests.cpp ;
|
||||
@@ -95,3 +96,55 @@ run exception/swap_exception_tests.cpp : : : <define>BOOST_UNORDERED_SWAP_METHOD
|
||||
run exception/merge_exception_tests.cpp ;
|
||||
|
||||
run quick.cpp ;
|
||||
|
||||
import ../../config/checks/config : requires ;
|
||||
|
||||
CPP11 = [ requires cxx11_constexpr cxx11_noexcept cxx11_decltype cxx11_alignas ] ;
|
||||
|
||||
rule build_foa ( name )
|
||||
{
|
||||
run unordered/$(name).cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_$(name) ;
|
||||
}
|
||||
|
||||
build_foa fwd_set_test ;
|
||||
build_foa fwd_map_test ;
|
||||
build_foa compile_set ;
|
||||
build_foa compile_map ;
|
||||
build_foa noexcept_tests ;
|
||||
run unordered/link_test_1.cpp unordered/link_test_2.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_link_test ;
|
||||
build_foa incomplete_test ;
|
||||
build_foa simple_tests ;
|
||||
build_foa equivalent_keys_tests ;
|
||||
build_foa constructor_tests ;
|
||||
build_foa copy_tests ;
|
||||
build_foa move_tests ;
|
||||
build_foa post_move_tests ;
|
||||
build_foa assign_tests ;
|
||||
build_foa insert_tests ;
|
||||
build_foa insert_hint_tests ;
|
||||
build_foa emplace_tests ;
|
||||
build_foa erase_tests ;
|
||||
build_foa merge_tests ;
|
||||
build_foa find_tests ;
|
||||
build_foa at_tests ;
|
||||
build_foa load_factor_tests ;
|
||||
build_foa rehash_tests ;
|
||||
build_foa equality_tests ;
|
||||
build_foa swap_tests ;
|
||||
run unordered/scoped_allocator.cpp : : : $(CPP11) <toolset>msvc-14.0:<build>no <define>BOOST_UNORDERED_FOA_TESTS : foa_scoped_allocator ;
|
||||
build_foa transparent_tests ;
|
||||
build_foa reserve_tests ;
|
||||
build_foa contains_tests ;
|
||||
build_foa erase_if ;
|
||||
build_foa scary_tests ;
|
||||
build_foa init_type_insert_tests ;
|
||||
|
||||
run exception/constructor_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_constructor_exception_tests ;
|
||||
run exception/copy_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_copy_exception_tests ;
|
||||
run exception/assign_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_assign_exception_tests ;
|
||||
run exception/move_assign_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_move_assign_exception_tests ;
|
||||
run exception/insert_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_insert_exception_tests ;
|
||||
run exception/erase_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_erase_exception_tests ;
|
||||
run exception/rehash_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_rehash_exception_tests ;
|
||||
run exception/swap_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_swap_exception_tests ;
|
||||
run exception/merge_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_merge_exception_tests ;
|
||||
|
||||
@@ -1,17 +1,33 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../objects/exception.hpp"
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<test::exception::object,
|
||||
test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> >
|
||||
test_set;
|
||||
|
||||
typedef boost::unordered_flat_map<test::exception::object,
|
||||
test::exception::object, test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> >
|
||||
test_map;
|
||||
|
||||
typedef boost::unordered_flat_set<
|
||||
std::pair<test::exception::object, test::exception::object>,
|
||||
test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> >
|
||||
test_pair_set;
|
||||
|
||||
#define CONTAINER_SEQ (test_set)(test_map)
|
||||
#define CONTAINER_PAIR_SEQ (test_pair_set)(test_map)
|
||||
#else
|
||||
typedef boost::unordered_set<test::exception::object, test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> >
|
||||
@@ -42,3 +58,5 @@ typedef boost::unordered_multiset<
|
||||
#define CONTAINER_SEQ (test_set)(test_multiset)(test_map)(test_multimap)
|
||||
#define CONTAINER_PAIR_SEQ \
|
||||
(test_pair_set)(test_pair_multiset)(test_map)(test_multimap)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include "./containers.hpp"
|
||||
@@ -95,7 +96,7 @@ void insert_rehash_exception_test(
|
||||
T*, Inserter insert, test::random_generator gen)
|
||||
{
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
T x;
|
||||
T x(1);
|
||||
rehash_prep(x);
|
||||
|
||||
test::random_values<T> v2(5, gen);
|
||||
@@ -221,16 +222,41 @@ struct emplace_lvalue_pos_type
|
||||
} emplace_lvalue_pos;
|
||||
|
||||
// Run the exception tests in various combinations.
|
||||
using test::default_generator;
|
||||
using test::limited_range;
|
||||
using test::generate_collisions;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
test_set* test_set_;
|
||||
test_map* test_map_;
|
||||
|
||||
// clang-format off
|
||||
UNORDERED_TEST(insert_exception_test,
|
||||
((test_set_)(test_map_))
|
||||
((insert_lvalue)(insert_lvalue_begin)(insert_lvalue_end)
|
||||
(insert_lvalue_pos)(insert_single_item_range)
|
||||
(emplace_lvalue)(emplace_lvalue_begin)(emplace_lvalue_end)
|
||||
(emplace_lvalue_pos)
|
||||
)
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(insert_rehash_exception_test,
|
||||
((test_set_)(test_map_))
|
||||
((insert_lvalue)(insert_lvalue_begin)(insert_lvalue_end)
|
||||
(insert_lvalue_pos)(insert_single_item_range)
|
||||
(emplace_lvalue)(emplace_lvalue_begin)(emplace_lvalue_end)
|
||||
(emplace_lvalue_pos)
|
||||
)
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
// clang-format on
|
||||
#else
|
||||
test_set* test_set_;
|
||||
test_multiset* test_multiset_;
|
||||
test_map* test_map_;
|
||||
test_multimap* test_multimap_;
|
||||
|
||||
using test::default_generator;
|
||||
using test::limited_range;
|
||||
using test::generate_collisions;
|
||||
|
||||
// clang-format off
|
||||
UNORDERED_TEST(insert_exception_test,
|
||||
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
|
||||
@@ -252,6 +278,7 @@ UNORDERED_TEST(insert_rehash_exception_test,
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
// Repeat insert tests with pairs
|
||||
|
||||
@@ -259,8 +286,13 @@ struct pair_emplace_type : inserter_base
|
||||
{
|
||||
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
x.emplace(std::piecewise_construct, std::make_tuple(it->first),
|
||||
std::make_tuple(it->second));
|
||||
#else
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(it->first), boost::make_tuple(it->second));
|
||||
#endif
|
||||
}
|
||||
} pair_emplace;
|
||||
|
||||
@@ -268,12 +300,34 @@ struct pair_emplace2_type : inserter_base
|
||||
{
|
||||
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
x.emplace_hint(x.begin(), std::piecewise_construct,
|
||||
std::make_tuple(it->first),
|
||||
std::make_tuple(it->second.tag1_, it->second.tag2_));
|
||||
#else
|
||||
x.emplace_hint(x.begin(), boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(it->first),
|
||||
boost::make_tuple(it->second.tag1_, it->second.tag2_));
|
||||
#endif
|
||||
}
|
||||
} pair_emplace2;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
test_pair_set* test_pair_set_;
|
||||
|
||||
// clang-format off
|
||||
UNORDERED_TEST(insert_exception_test,
|
||||
((test_pair_set_)(test_map_))
|
||||
((pair_emplace)(pair_emplace2))
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
UNORDERED_TEST(insert_rehash_exception_test,
|
||||
((test_pair_set_)(test_map_))
|
||||
((pair_emplace)(pair_emplace2))
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
// clang-format on
|
||||
#else
|
||||
test_pair_set* test_pair_set_;
|
||||
test_pair_multiset* test_pair_multiset_;
|
||||
|
||||
@@ -289,6 +343,7 @@ UNORDERED_TEST(insert_rehash_exception_test,
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
// Test inserting using operator[]
|
||||
|
||||
@@ -393,7 +448,7 @@ template <typename T>
|
||||
void insert_range_rehash_exception_test(T*, test::random_generator gen)
|
||||
{
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
T x;
|
||||
T x(1);
|
||||
rehash_prep(x);
|
||||
|
||||
test::random_values<T> v2(5, gen);
|
||||
@@ -401,6 +456,19 @@ void insert_range_rehash_exception_test(T*, test::random_generator gen)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
// clang-format off
|
||||
UNORDERED_TEST(insert_range_exception_test,
|
||||
((test_set_)(test_map_))
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(insert_range_rehash_exception_test,
|
||||
((test_set_)(test_map_))
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
// clang-format on
|
||||
#else
|
||||
// clang-format off
|
||||
UNORDERED_TEST(insert_range_exception_test,
|
||||
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
|
||||
@@ -412,5 +480,6 @@ UNORDERED_TEST(insert_range_rehash_exception_test,
|
||||
((default_generator)(limited_range)(generate_collisions))
|
||||
)
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright 2017-2018 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -52,6 +53,53 @@ void merge_exception_test(T1 const*, T2 const*, std::size_t count12, int tag12,
|
||||
EXCEPTION_LOOP(merge_exception_test(x, y))
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::exception::object, test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> >* test_set_;
|
||||
boost::unordered_flat_map<test::exception::object, test::exception::object,
|
||||
test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> >* test_map_;
|
||||
|
||||
// clang-format off
|
||||
UNORDERED_MULTI_TEST(set_merge, merge_exception_test,
|
||||
((test_set_))
|
||||
((test_set_))
|
||||
((0x0000)(0x6400)(0x0064)(0x0a64)(0x3232))
|
||||
((0x0000)(0x0001)(0x0102))
|
||||
((default_generator)(limited_range))
|
||||
((default_generator)(limited_range))
|
||||
)
|
||||
UNORDERED_MULTI_TEST(map_merge, merge_exception_test,
|
||||
((test_map_))
|
||||
((test_map_))
|
||||
((0x0000)(0x6400)(0x0064)(0x0a64)(0x3232))
|
||||
((0x0101)(0x0200)(0x0201))
|
||||
((default_generator)(limited_range))
|
||||
((default_generator)(limited_range))
|
||||
)
|
||||
// Run fewer generate_collisions tests, as they're slow.
|
||||
UNORDERED_MULTI_TEST(set_merge_collisions, merge_exception_test,
|
||||
((test_set_))
|
||||
((test_set_))
|
||||
((0x0a0a))
|
||||
((0x0202)(0x0100)(0x0201))
|
||||
((generate_collisions))
|
||||
((generate_collisions))
|
||||
)
|
||||
UNORDERED_MULTI_TEST(map_merge_collisions, merge_exception_test,
|
||||
((test_map_))
|
||||
((test_map_))
|
||||
((0x0a0a))
|
||||
((0x0000)(0x0002)(0x0102))
|
||||
((generate_collisions))
|
||||
((generate_collisions))
|
||||
)
|
||||
#else
|
||||
boost::unordered_set<test::exception::object, test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> >* test_set_;
|
||||
@@ -65,10 +113,6 @@ boost::unordered_multimap<test::exception::object, test::exception::object,
|
||||
test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> >* test_multimap_;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
// clang-format off
|
||||
UNORDERED_MULTI_TEST(set_merge, merge_exception_test,
|
||||
((test_set_)(test_multiset_))
|
||||
@@ -104,5 +148,6 @@ UNORDERED_MULTI_TEST(map_merge_collisions, merge_exception_test,
|
||||
((generate_collisions))
|
||||
)
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
RUN_TESTS_QUIET()
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./containers.hpp"
|
||||
|
||||
#if defined(BOOST_UNORDERED_FOA_TESTS)
|
||||
#define BOOST_UNORDERED_FOA_WEAK_GUARANTEE_SWAP_EXCEPTIONS_TESTS
|
||||
#endif
|
||||
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -53,11 +54,22 @@ namespace test {
|
||||
if (test::has_unique_keys<X>::value && count != 1)
|
||||
BOOST_ERROR("Non-unique key.");
|
||||
|
||||
#if !defined(BOOST_UNORDERED_FOA_WEAK_GUARANTEE_SWAP_EXCEPTIONS_TESTS)
|
||||
// we conditionally compile this check because our FOA implementation only
|
||||
// exhibits the weak guarantee when swapping throws
|
||||
//
|
||||
// in this case, the hasher may be changed before the predicate and the
|
||||
// arrays are swapped in which case, we can can find an element by
|
||||
// iteration but unfortunately, it's in the wrong slot according to the
|
||||
// new hash function so count(key) can wind up returning nothing when
|
||||
// there really is something
|
||||
if (x1.count(key) != count) {
|
||||
BOOST_ERROR("Incorrect output of count.");
|
||||
std::cerr << x1.count(key) << "," << count << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
// Check that the keys are in the correct bucket and are
|
||||
// adjacent in the bucket.
|
||||
typename X::size_type bucket = x1.bucket(key);
|
||||
@@ -86,6 +98,7 @@ namespace test {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// Check that size matches up.
|
||||
@@ -104,6 +117,7 @@ namespace test {
|
||||
if (fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
|
||||
BOOST_ERROR("x1.load_factor() doesn't match actual load_factor.");
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
// Check that size in the buckets matches up.
|
||||
|
||||
typename X::size_type bucket_size = 0;
|
||||
@@ -120,6 +134,7 @@ namespace test {
|
||||
BOOST_ERROR("x1.size() doesn't match bucket size.");
|
||||
std::cout << x1.size() << "/" << bucket_size << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
22
test/helpers/unordered.hpp
Normal file
22
test/helpers/unordered.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
// Copyright 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_UNORDERED_TEST_HELPERS_UNORDERED_HEADER)
|
||||
#define BOOST_UNORDERED_TEST_HELPERS_UNORDERED_HEADER
|
||||
|
||||
// clang-format off
|
||||
#include "prefix.hpp"
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
#include <boost/unordered/unordered_flat_set.hpp>
|
||||
#include <boost/unordered/unordered_flat_map.hpp>
|
||||
#include <boost/unordered/detail/implementation.hpp>
|
||||
#else
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#endif
|
||||
#include "postfix.hpp"
|
||||
// clang-format on
|
||||
|
||||
#endif
|
||||
@@ -11,6 +11,7 @@
|
||||
#if !defined(BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER)
|
||||
#define BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/pointer_traits.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
@@ -320,7 +321,7 @@ namespace test {
|
||||
bool operator!() const { return !ptr_; }
|
||||
|
||||
static ptr pointer_to(T& p) {
|
||||
return ptr(&p);
|
||||
return ptr(boost::addressof(p));
|
||||
}
|
||||
|
||||
// I'm not using the safe bool idiom because the containers should be
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
@@ -45,6 +41,7 @@ namespace assign_tests {
|
||||
BOOST_TEST(x.empty());
|
||||
BOOST_TEST(test::equivalent(x.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(x.key_eq(), eq));
|
||||
BOOST_TEST(test::detail::tracker.count_allocations == 0);
|
||||
}
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "assign_tests1.2\n";
|
||||
@@ -94,6 +91,7 @@ namespace assign_tests {
|
||||
BOOST_TEST(test::equivalent(x1.key_eq(), eq1));
|
||||
BOOST_TEST(test::equivalent(x2.hash_function(), hf1));
|
||||
BOOST_TEST(test::equivalent(x2.key_eq(), eq1));
|
||||
BOOST_TEST(test::detail::tracker.count_allocations == 0);
|
||||
test::check_container(x1, x2);
|
||||
}
|
||||
|
||||
@@ -199,6 +197,54 @@ namespace assign_tests {
|
||||
}
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
template <typename T> bool is_propagate(T*)
|
||||
{
|
||||
return T::allocator_type::is_propagate_on_assign;
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_map;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
test_set_prop_assign;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
test_map_prop_assign;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
test_set_no_prop_assign;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
test_map_no_prop_assign;
|
||||
|
||||
UNORDERED_AUTO_TEST (check_traits) {
|
||||
BOOST_TEST(!is_propagate(test_set));
|
||||
BOOST_TEST(is_propagate(test_set_prop_assign));
|
||||
BOOST_TEST(!is_propagate(test_set_no_prop_assign));
|
||||
}
|
||||
|
||||
UNORDERED_TEST(assign_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_map)(test_set_prop_assign)(test_map_prop_assign)(test_set_no_prop_assign)(test_map_no_prop_assign))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(assign_tests2,
|
||||
((test_set)(test_map)(test_set_prop_assign)(test_map_prop_assign)(test_set_no_prop_assign)(test_map_no_prop_assign))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
@@ -239,15 +285,6 @@ namespace assign_tests {
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
test_multimap_no_prop_assign;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
template <typename T> bool is_propagate(T*)
|
||||
{
|
||||
return T::allocator_type::is_propagate_on_assign;
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (check_traits) {
|
||||
BOOST_TEST(!is_propagate(test_set));
|
||||
BOOST_TEST(is_propagate(test_set_prop_assign));
|
||||
@@ -269,13 +306,18 @@ namespace assign_tests {
|
||||
test_set_no_prop_assign)(test_multiset_no_prop_assign)(
|
||||
test_map_no_prop_assign)(test_multimap_no_prop_assign))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
UNORDERED_AUTO_TEST (assign_default_initializer_list) {
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
|
||||
std::initializer_list<std::pair<int const, int> > init;
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<int, int> x1;
|
||||
#else
|
||||
boost::unordered_map<int, int> x1;
|
||||
#endif
|
||||
x1[25] = 3;
|
||||
x1[16] = 10;
|
||||
BOOST_TEST(!x1.empty());
|
||||
@@ -289,7 +331,11 @@ namespace assign_tests {
|
||||
UNORDERED_AUTO_TEST (assign_initializer_list) {
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> x;
|
||||
#else
|
||||
boost::unordered_set<int> x;
|
||||
#endif
|
||||
x.insert(10);
|
||||
x.insert(20);
|
||||
x = {1, 2, -10};
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
|
||||
// Copyright 2007-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include <string>
|
||||
@@ -17,8 +14,13 @@ namespace at_tests {
|
||||
UNORDERED_AUTO_TEST (at_tests) {
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Create Map" << std::endl;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<std::string, int> x;
|
||||
boost::unordered_flat_map<std::string, int> const& x_const(x);
|
||||
#else
|
||||
boost::unordered_map<std::string, int> x;
|
||||
boost::unordered_map<std::string, int> const& x_const(x);
|
||||
#endif
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Check empty container" << std::endl;
|
||||
|
||||
|
||||
@@ -1,23 +1,41 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// This test creates the containers with members that meet their minimum
|
||||
// requirements. Makes sure everything compiles and is defined correctly.
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/minimal.hpp"
|
||||
#include "./compile_tests.hpp"
|
||||
|
||||
// Explicit instantiation to catch compile-time errors
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
|
||||
// emulates what was already done for previous tests but without leaking to
|
||||
// the detail namespace
|
||||
//
|
||||
template <typename K, typename T, typename H, typename P, typename A>
|
||||
class instantiate_flat_map
|
||||
{
|
||||
typedef boost::unordered_flat_map<K, T, H, P, A> container;
|
||||
container x;
|
||||
};
|
||||
|
||||
template class instantiate_flat_map<int, int, boost::hash<int>,
|
||||
std::equal_to<int>, test::minimal::allocator<int> >;
|
||||
|
||||
template class instantiate_flat_map<test::minimal::assignable const,
|
||||
test::minimal::default_assignable const,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<int> >;
|
||||
|
||||
#else
|
||||
#define INSTANTIATE(type) \
|
||||
template class boost::unordered::detail::instantiate_##type
|
||||
|
||||
@@ -35,6 +53,7 @@ INSTANTIATE(multimap)<test::minimal::assignable, test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<int> >;
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (test0) {
|
||||
test::minimal::constructor_param x;
|
||||
@@ -45,6 +64,19 @@ UNORDERED_AUTO_TEST (test0) {
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<int, int> int_map;
|
||||
|
||||
boost::unordered_flat_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
int_map2;
|
||||
|
||||
boost::unordered_flat_map<test::minimal::assignable,
|
||||
test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
map;
|
||||
#else
|
||||
boost::unordered_map<int, int> int_map;
|
||||
|
||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
@@ -56,11 +88,13 @@ UNORDERED_AUTO_TEST (test0) {
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
map;
|
||||
#endif
|
||||
|
||||
container_test(int_map, std::pair<int const, int>(0, 0));
|
||||
container_test(int_map2, std::pair<int const, int>(0, 0));
|
||||
container_test(map, value);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
||||
|
||||
boost::unordered_multimap<int, int> int_multimap;
|
||||
@@ -78,6 +112,7 @@ UNORDERED_AUTO_TEST (test0) {
|
||||
container_test(int_multimap, std::pair<int const, int>(0, 0));
|
||||
container_test(int_multimap2, std::pair<int const, int>(0, 0));
|
||||
container_test(multimap, value);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (equality_tests) {
|
||||
@@ -85,6 +120,22 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
||||
test::minimal::copy_constructible_equality_comparable>
|
||||
value_type;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<int, int> int_map;
|
||||
|
||||
boost::unordered_flat_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
int_map2;
|
||||
|
||||
boost::unordered_flat_map<
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
map;
|
||||
#else
|
||||
boost::unordered_map<int, int> int_map;
|
||||
|
||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
@@ -98,11 +149,13 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
map;
|
||||
#endif
|
||||
|
||||
equality_test(int_map);
|
||||
equality_test(int_map2);
|
||||
equality_test(map);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_multimap<int, int> int_multimap;
|
||||
|
||||
boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
@@ -121,6 +174,7 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
||||
equality_test(int_multimap);
|
||||
equality_test(int_multimap2);
|
||||
equality_test(multimap);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (test1) {
|
||||
@@ -131,11 +185,19 @@ UNORDERED_AUTO_TEST (test1) {
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<int, int> map;
|
||||
|
||||
boost::unordered_flat_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
map2;
|
||||
#else
|
||||
boost::unordered_map<int, int> map;
|
||||
|
||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
map2;
|
||||
#endif
|
||||
|
||||
unordered_unique_test(map, map_value);
|
||||
unordered_map_test(map, value, value);
|
||||
@@ -147,6 +209,7 @@ UNORDERED_AUTO_TEST (test1) {
|
||||
unordered_copyable_test(map2, value, map_value, hash, equal_to);
|
||||
unordered_map_functions(map2, value, value);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
||||
|
||||
boost::unordered_multimap<int, int> multimap;
|
||||
@@ -162,6 +225,7 @@ UNORDERED_AUTO_TEST (test1) {
|
||||
unordered_equivalent_test(multimap2, map_value);
|
||||
unordered_map_test(multimap2, value, value);
|
||||
unordered_copyable_test(multimap2, value, map_value, hash, equal_to);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (test2) {
|
||||
@@ -178,28 +242,46 @@ UNORDERED_AUTO_TEST (test2) {
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<test::minimal::assignable,
|
||||
test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<map_value_type> >
|
||||
map;
|
||||
#else
|
||||
boost::unordered_map<test::minimal::assignable, test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<map_value_type> >
|
||||
map;
|
||||
#endif
|
||||
|
||||
unordered_unique_test(map, map_value);
|
||||
unordered_map_test(map, assignable, assignable);
|
||||
unordered_copyable_test(map, assignable, map_value, hash, equal_to);
|
||||
unordered_map_member_test(map, map_value);
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<test::minimal::assignable,
|
||||
test::minimal::default_assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<map_value_type> >
|
||||
map2;
|
||||
#else
|
||||
boost::unordered_map<test::minimal::assignable,
|
||||
test::minimal::default_assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<map_value_type> >
|
||||
map2;
|
||||
#endif
|
||||
|
||||
test::minimal::default_assignable default_assignable;
|
||||
|
||||
unordered_map_functions(map2, assignable, default_assignable);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
||||
|
||||
boost::unordered_multimap<test::minimal::assignable,
|
||||
@@ -212,6 +294,7 @@ UNORDERED_AUTO_TEST (test2) {
|
||||
unordered_map_test(multimap, assignable, assignable);
|
||||
unordered_copyable_test(multimap, assignable, map_value, hash, equal_to);
|
||||
unordered_map_member_test(multimap, map_value);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test for ambiguity when using key convertible from iterator
|
||||
@@ -232,6 +315,11 @@ std::size_t hash_value(lwg2059_key x)
|
||||
bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
|
||||
|
||||
UNORDERED_AUTO_TEST (lwg2059) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<lwg2059_key, int> x;
|
||||
x.emplace(lwg2059_key(10), 5);
|
||||
x.erase(x.begin());
|
||||
#else
|
||||
{
|
||||
boost::unordered_map<lwg2059_key, int> x;
|
||||
x.emplace(lwg2059_key(10), 5);
|
||||
@@ -243,6 +331,7 @@ UNORDERED_AUTO_TEST (lwg2059) {
|
||||
x.emplace(lwg2059_key(10), 5);
|
||||
x.erase(x.begin());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// This test creates the containers with members that meet their minimum
|
||||
// requirements. Makes sure everything compiles and is defined correctly.
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/minimal.hpp"
|
||||
@@ -18,6 +15,28 @@
|
||||
|
||||
// Explicit instantiation to catch compile-time errors
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
|
||||
// emulates what was already done for previous tests but without leaking to
|
||||
// the detail namespace
|
||||
//
|
||||
template <typename T, typename H, typename P, typename A>
|
||||
class instantiate_flat_set
|
||||
{
|
||||
typedef boost::unordered_flat_set<T, H, P, A> container;
|
||||
container x;
|
||||
};
|
||||
|
||||
template class instantiate_flat_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::allocator<int> >;
|
||||
|
||||
template class instantiate_flat_set<test::minimal::assignable const,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<int> >;
|
||||
|
||||
#else
|
||||
|
||||
#define INSTANTIATE(type) \
|
||||
template class boost::unordered::detail::instantiate_##type
|
||||
|
||||
@@ -35,6 +54,21 @@ INSTANTIATE(multiset)<test::minimal::assignable,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<int> >;
|
||||
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (type_traits) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int> set_type;
|
||||
#else
|
||||
typedef boost::unordered_set<int> set_type;
|
||||
#endif
|
||||
|
||||
typedef set_type::iterator iterator;
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_same<int const&,
|
||||
std::iterator_traits<iterator>::reference>::value);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (test0) {
|
||||
test::minimal::constructor_param x;
|
||||
|
||||
@@ -42,6 +76,19 @@ UNORDERED_AUTO_TEST (test0) {
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> int_set;
|
||||
|
||||
boost::unordered_flat_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
int_set2;
|
||||
|
||||
boost::unordered_flat_set<test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >
|
||||
set;
|
||||
#else
|
||||
boost::unordered_set<int> int_set;
|
||||
|
||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
@@ -53,11 +100,13 @@ UNORDERED_AUTO_TEST (test0) {
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >
|
||||
set;
|
||||
#endif
|
||||
|
||||
container_test(int_set, 0);
|
||||
container_test(int_set2, 0);
|
||||
container_test(set, assignable);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<int> int_multiset;
|
||||
@@ -75,11 +124,27 @@ UNORDERED_AUTO_TEST (test0) {
|
||||
container_test(int_multiset, 0);
|
||||
container_test(int_multiset2, 0);
|
||||
container_test(multiset, assignable);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (equality_tests) {
|
||||
typedef test::minimal::copy_constructible_equality_comparable value_type;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> int_set;
|
||||
|
||||
boost::unordered_flat_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
int_set2;
|
||||
|
||||
boost::unordered_flat_set<
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
set;
|
||||
#else
|
||||
boost::unordered_set<int> int_set;
|
||||
|
||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
@@ -92,11 +157,13 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
set;
|
||||
#endif
|
||||
|
||||
equality_test(int_set);
|
||||
equality_test(int_set2);
|
||||
equality_test(set);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_multiset<int> int_multiset;
|
||||
|
||||
boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
|
||||
@@ -114,6 +181,7 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
||||
equality_test(int_multiset);
|
||||
equality_test(int_multiset2);
|
||||
equality_test(multiset);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (test1) {
|
||||
@@ -122,12 +190,19 @@ UNORDERED_AUTO_TEST (test1) {
|
||||
int value = 0;
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set." << std::endl;
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> set;
|
||||
|
||||
boost::unordered_flat_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
set2;
|
||||
#else
|
||||
boost::unordered_set<int> set;
|
||||
|
||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
set2;
|
||||
#endif
|
||||
|
||||
unordered_unique_test(set, value);
|
||||
unordered_set_test(set, value);
|
||||
@@ -137,6 +212,7 @@ UNORDERED_AUTO_TEST (test1) {
|
||||
unordered_set_test(set2, value);
|
||||
unordered_copyable_test(set2, value, value, hash, equal_to);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset." << std::endl;
|
||||
|
||||
boost::unordered_multiset<int> multiset;
|
||||
@@ -152,6 +228,7 @@ UNORDERED_AUTO_TEST (test1) {
|
||||
unordered_equivalent_test(multiset2, value);
|
||||
unordered_set_test(multiset2, value);
|
||||
unordered_copyable_test(multiset2, value, value, hash, equal_to);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (test2) {
|
||||
@@ -163,18 +240,26 @@ UNORDERED_AUTO_TEST (test2) {
|
||||
test::minimal::equal_to<test::minimal::assignable> equal_to(x);
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >
|
||||
set;
|
||||
#else
|
||||
boost::unordered_set<test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >
|
||||
set;
|
||||
#endif
|
||||
|
||||
unordered_unique_test(set, assignable);
|
||||
unordered_set_test(set, assignable);
|
||||
unordered_copyable_test(set, assignable, assignable, hash, equal_to);
|
||||
unordered_set_member_test(set, assignable);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<test::minimal::assignable,
|
||||
@@ -187,6 +272,7 @@ UNORDERED_AUTO_TEST (test2) {
|
||||
unordered_set_test(multiset, assignable);
|
||||
unordered_copyable_test(multiset, assignable, assignable, hash, equal_to);
|
||||
unordered_set_member_test(multiset, assignable);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (movable1_tests) {
|
||||
@@ -197,17 +283,25 @@ UNORDERED_AUTO_TEST (movable1_tests) {
|
||||
test::minimal::equal_to<test::minimal::movable1> equal_to(x);
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::minimal::movable1,
|
||||
test::minimal::hash<test::minimal::movable1>,
|
||||
test::minimal::equal_to<test::minimal::movable1>,
|
||||
test::minimal::allocator<test::minimal::movable1> >
|
||||
set;
|
||||
#else
|
||||
boost::unordered_set<test::minimal::movable1,
|
||||
test::minimal::hash<test::minimal::movable1>,
|
||||
test::minimal::equal_to<test::minimal::movable1>,
|
||||
test::minimal::allocator<test::minimal::movable1> >
|
||||
set;
|
||||
#endif
|
||||
|
||||
// unordered_unique_test(set, movable1);
|
||||
unordered_set_test(set, movable1);
|
||||
unordered_movable_test(set, movable1, movable1, hash, equal_to);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<test::minimal::movable1,
|
||||
@@ -219,6 +313,7 @@ UNORDERED_AUTO_TEST (movable1_tests) {
|
||||
// unordered_equivalent_test(multiset, movable1);
|
||||
unordered_set_test(multiset, movable1);
|
||||
unordered_movable_test(multiset, movable1, movable1, hash, equal_to);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (movable2_tests) {
|
||||
@@ -229,17 +324,25 @@ UNORDERED_AUTO_TEST (movable2_tests) {
|
||||
test::minimal::equal_to<test::minimal::movable2> equal_to(x);
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::minimal::movable2,
|
||||
test::minimal::hash<test::minimal::movable2>,
|
||||
test::minimal::equal_to<test::minimal::movable2>,
|
||||
test::minimal::allocator<test::minimal::movable2> >
|
||||
set;
|
||||
#else
|
||||
boost::unordered_set<test::minimal::movable2,
|
||||
test::minimal::hash<test::minimal::movable2>,
|
||||
test::minimal::equal_to<test::minimal::movable2>,
|
||||
test::minimal::allocator<test::minimal::movable2> >
|
||||
set;
|
||||
#endif
|
||||
|
||||
// unordered_unique_test(set, movable2);
|
||||
unordered_set_test(set, movable2);
|
||||
unordered_movable_test(set, movable2, movable2, hash, equal_to);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<test::minimal::movable2,
|
||||
@@ -251,6 +354,7 @@ UNORDERED_AUTO_TEST (movable2_tests) {
|
||||
// unordered_equivalent_test(multiset, movable2);
|
||||
unordered_set_test(multiset, movable2);
|
||||
unordered_movable_test(multiset, movable2, movable2, hash, equal_to);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (destructible_tests) {
|
||||
@@ -261,14 +365,21 @@ UNORDERED_AUTO_TEST (destructible_tests) {
|
||||
test::minimal::equal_to<test::minimal::destructible> equal_to(x);
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::minimal::destructible,
|
||||
test::minimal::hash<test::minimal::destructible>,
|
||||
test::minimal::equal_to<test::minimal::destructible> >
|
||||
set;
|
||||
#else
|
||||
boost::unordered_set<test::minimal::destructible,
|
||||
test::minimal::hash<test::minimal::destructible>,
|
||||
test::minimal::equal_to<test::minimal::destructible> >
|
||||
set;
|
||||
#endif
|
||||
|
||||
unordered_destructible_test(set);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<test::minimal::destructible,
|
||||
@@ -277,6 +388,7 @@ UNORDERED_AUTO_TEST (destructible_tests) {
|
||||
multiset;
|
||||
|
||||
unordered_destructible_test(multiset);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test for ambiguity when using key convertible from iterator
|
||||
@@ -297,6 +409,11 @@ std::size_t hash_value(lwg2059_key x)
|
||||
bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
|
||||
|
||||
UNORDERED_AUTO_TEST (lwg2059) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<lwg2059_key> x;
|
||||
x.emplace(lwg2059_key(10));
|
||||
x.erase(x.begin());
|
||||
#else
|
||||
{
|
||||
boost::unordered_set<lwg2059_key> x;
|
||||
x.emplace(lwg2059_key(10));
|
||||
@@ -308,6 +425,7 @@ UNORDERED_AUTO_TEST (lwg2059) {
|
||||
x.emplace(lwg2059_key(10));
|
||||
x.erase(x.begin());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -70,9 +71,19 @@ template <class X, class T> void container_test(X& r, T const&)
|
||||
typedef typename X::reference reference;
|
||||
typedef typename X::const_reference const_reference;
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename X::node_type node_type;
|
||||
#endif
|
||||
|
||||
typedef typename X::allocator_type allocator_type;
|
||||
typedef typename X::pointer pointer;
|
||||
typedef typename X::const_pointer const_pointer;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<pointer,
|
||||
typename boost::allocator_pointer<allocator_type>::type>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<const_pointer,
|
||||
typename boost::allocator_const_pointer<allocator_type>::type>::value));
|
||||
|
||||
// value_type
|
||||
|
||||
@@ -97,8 +108,10 @@ template <class X, class T> void container_test(X& r, T const&)
|
||||
|
||||
// node_type
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<allocator_type, typename node_type::allocator_type>::value));
|
||||
#endif
|
||||
|
||||
// difference_type
|
||||
|
||||
@@ -167,6 +180,7 @@ template <class X, class T> void container_test(X& r, T const&)
|
||||
sink(X(rvalue(a_const), m));
|
||||
X c3(rvalue(a_const), m);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
// node_type
|
||||
|
||||
implicit_construct<node_type const>();
|
||||
@@ -193,6 +207,7 @@ template <class X, class T> void container_test(X& r, T const&)
|
||||
test::check_return_type<bool>::equals(n_const.empty());
|
||||
TEST_NOEXCEPT_EXPR(!n_const);
|
||||
TEST_NOEXCEPT_EXPR(n_const.empty());
|
||||
#endif
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
@@ -262,24 +277,30 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
|
||||
|
||||
typedef typename X::iterator iterator;
|
||||
typedef typename X::const_iterator const_iterator;
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename X::local_iterator local_iterator;
|
||||
typedef typename X::const_local_iterator const_local_iterator;
|
||||
#endif
|
||||
typedef typename std::iterator_traits<iterator>::pointer iterator_pointer;
|
||||
typedef typename std::iterator_traits<const_iterator>::pointer
|
||||
const_iterator_pointer;
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename std::iterator_traits<local_iterator>::pointer
|
||||
local_iterator_pointer;
|
||||
typedef typename std::iterator_traits<const_local_iterator>::pointer
|
||||
const_local_iterator_pointer;
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type const*, iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type const*, const_iterator_pointer>::value));
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type const*, local_iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
|
||||
#endif
|
||||
|
||||
// pointer_traits<iterator>
|
||||
|
||||
@@ -299,6 +320,8 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<std::ptrdiff_t,
|
||||
typename boost::pointer_traits<const_iterator>::difference_type>::value));
|
||||
|
||||
(void) r;
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
// pointer_traits<local_iterator>
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<local_iterator,
|
||||
@@ -330,6 +353,7 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
|
||||
r.emplace(boost::move(k_lvalue));
|
||||
node_type n1 = r.extract(r.begin());
|
||||
test::check_return_type<value_type>::equals_ref(n1.value());
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X, class Key, class T>
|
||||
@@ -345,23 +369,29 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
|
||||
typedef typename X::iterator iterator;
|
||||
typedef typename X::const_iterator const_iterator;
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename X::local_iterator local_iterator;
|
||||
typedef typename X::const_local_iterator const_local_iterator;
|
||||
#endif
|
||||
typedef typename std::iterator_traits<iterator>::pointer iterator_pointer;
|
||||
typedef typename std::iterator_traits<const_iterator>::pointer
|
||||
const_iterator_pointer;
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename std::iterator_traits<local_iterator>::pointer
|
||||
local_iterator_pointer;
|
||||
typedef typename std::iterator_traits<const_local_iterator>::pointer
|
||||
const_local_iterator_pointer;
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type*, iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type const*, const_iterator_pointer>::value));
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type*, local_iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
|
||||
#endif
|
||||
|
||||
// pointer_traits<iterator>
|
||||
|
||||
@@ -381,6 +411,7 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<std::ptrdiff_t,
|
||||
typename boost::pointer_traits<const_iterator>::difference_type>::value));
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
// pointer_traits<local_iterator>
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<local_iterator,
|
||||
@@ -409,6 +440,7 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<T, node_mapped_type>::value));
|
||||
// Superfluous,but just to make sure.
|
||||
BOOST_STATIC_ASSERT((!boost::is_const<node_key_type>::value));
|
||||
#endif
|
||||
|
||||
// Calling functions
|
||||
|
||||
@@ -427,8 +459,12 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
r.emplace(k_lvalue, v_lvalue);
|
||||
r.emplace(rvalue(k), rvalue(v));
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
r.emplace(std::piecewise_construct, std::make_tuple(k), std::make_tuple(v));
|
||||
#else
|
||||
r.emplace(boost::unordered::piecewise_construct, boost::make_tuple(k),
|
||||
boost::make_tuple(v));
|
||||
#endif
|
||||
|
||||
// Emplace with hint
|
||||
|
||||
@@ -436,9 +472,15 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
r.emplace_hint(r.begin(), k_lvalue, v_lvalue);
|
||||
r.emplace_hint(r.begin(), rvalue(k), rvalue(v));
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
r.emplace_hint(r.begin(), std::piecewise_construct, std::make_tuple(k),
|
||||
std::make_tuple(v));
|
||||
#else
|
||||
r.emplace_hint(r.begin(), boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(k), boost::make_tuple(v));
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
// Extract
|
||||
|
||||
test::check_return_type<node_type>::equals(r.extract(r.begin()));
|
||||
@@ -461,6 +503,7 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
node_type n = r.extract(r.begin());
|
||||
test::check_return_type<node_key_type>::equals_ref(n.key());
|
||||
test::check_return_type<node_mapped_type>::equals_ref(n.mapped());
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X> void equality_test(X& r)
|
||||
@@ -479,6 +522,7 @@ template <class X, class T> void unordered_unique_test(X& r, T const& t)
|
||||
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
|
||||
test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename X::node_type node_type;
|
||||
typedef typename X::insert_return_type insert_return_type;
|
||||
|
||||
@@ -503,6 +547,7 @@ template <class X, class T> void unordered_unique_test(X& r, T const& t)
|
||||
test::check_return_type<iterator>::equals(insert_return.position);
|
||||
test::check_return_type<node_type>::equals_ref(insert_return.node);
|
||||
boost::swap(insert_return, insert_return2);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X, class T> void unordered_equivalent_test(X& r, T const& t)
|
||||
@@ -554,6 +599,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
||||
|
||||
typedef typename X::iterator iterator;
|
||||
typedef typename X::const_iterator const_iterator;
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename X::local_iterator local_iterator;
|
||||
typedef typename X::const_local_iterator const_local_iterator;
|
||||
|
||||
@@ -590,6 +636,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
||||
const_local_iterator_pointer;
|
||||
typedef typename std::iterator_traits<const_local_iterator>::reference
|
||||
const_local_iterator_reference;
|
||||
#endif
|
||||
typedef typename X::allocator_type allocator_type;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Key, key_type>::value));
|
||||
@@ -602,6 +649,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Pred, key_equal>::value));
|
||||
test::check_return_type<bool>::convertible(eq(k, k));
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<local_iterator_category, iterator_category>::value));
|
||||
@@ -622,6 +670,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
||||
const_iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<const_local_iterator_reference,
|
||||
const_iterator_reference>::value));
|
||||
#endif
|
||||
|
||||
X a;
|
||||
allocator_type m = a.get_allocator();
|
||||
@@ -667,6 +716,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
||||
test::check_return_type<std::pair<const_iterator, const_iterator> >::equals(
|
||||
b.equal_range(k));
|
||||
test::check_return_type<size_type>::equals(b.bucket_count());
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
test::check_return_type<size_type>::equals(b.max_bucket_count());
|
||||
test::check_return_type<size_type>::equals(b.bucket(k));
|
||||
test::check_return_type<size_type>::equals(b.bucket_size(0));
|
||||
@@ -680,6 +730,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
||||
test::check_return_type<const_local_iterator>::equals(b.cbegin(0));
|
||||
test::check_return_type<const_local_iterator>::equals(a.cend(0));
|
||||
test::check_return_type<const_local_iterator>::equals(b.cend(0));
|
||||
#endif
|
||||
|
||||
test::check_return_type<float>::equals(b.load_factor());
|
||||
test::check_return_type<float>::equals(b.max_load_factor());
|
||||
@@ -792,7 +843,11 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
X a10;
|
||||
a10.insert(t);
|
||||
q = a10.cbegin();
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_STATIC_ASSERT(std::is_same<void, decltype(a10.erase(q))>::value);
|
||||
#else
|
||||
test::check_return_type<iterator>::equals(a10.erase(q));
|
||||
#endif
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
@@ -807,10 +862,12 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
sink(a7a);
|
||||
sink(a9a);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename X::node_type node_type;
|
||||
typedef typename X::allocator_type allocator_type;
|
||||
node_type const n_const = a.extract(a.begin());
|
||||
test::check_return_type<allocator_type>::equals(n_const.get_allocator());
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X, class Key, class T, class Hash, class Pred>
|
||||
@@ -879,7 +936,11 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
||||
T v5(v);
|
||||
a10.insert(boost::move(v5));
|
||||
q = a10.cbegin();
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_STATIC_ASSERT(std::is_same<void, decltype(a10.erase(q))>::value);
|
||||
#else
|
||||
test::check_return_type<iterator>::equals(a10.erase(q));
|
||||
#endif
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2010 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
@@ -35,6 +31,7 @@ namespace constructor_tests {
|
||||
|
||||
T x(0, hf, eq);
|
||||
BOOST_TEST(x.empty());
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST(test::equivalent(x.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(x.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(x.get_allocator(), al));
|
||||
@@ -73,6 +70,7 @@ namespace constructor_tests {
|
||||
|
||||
T x;
|
||||
BOOST_TEST(x.empty());
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST(test::equivalent(x.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(x.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(x.get_allocator(), al));
|
||||
@@ -140,6 +138,7 @@ namespace constructor_tests {
|
||||
|
||||
T x(0, hf, eq, al);
|
||||
BOOST_TEST(x.empty());
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST(test::equivalent(x.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(x.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(x.get_allocator(), al));
|
||||
@@ -166,6 +165,7 @@ namespace constructor_tests {
|
||||
|
||||
T x(al);
|
||||
BOOST_TEST(x.empty());
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST(test::equivalent(x.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(x.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(x.get_allocator(), al));
|
||||
@@ -325,6 +325,7 @@ namespace constructor_tests {
|
||||
|
||||
T x(list);
|
||||
BOOST_TEST(x.empty());
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST(test::equivalent(x.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(x.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(x.get_allocator(), al));
|
||||
@@ -380,6 +381,104 @@ namespace constructor_tests {
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void no_alloc_default_construct_test(T*, test::random_generator)
|
||||
{
|
||||
UNORDERED_SUB_TEST("Construct 1")
|
||||
{
|
||||
T x;
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
UNORDERED_SUB_TEST("Construct 2")
|
||||
{
|
||||
{
|
||||
T x(0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
T x(1);
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_SUB_TEST("Construct 3")
|
||||
{
|
||||
test::random_values<T> v;
|
||||
T x(v.begin(), v.end());
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
UNORDERED_SUB_TEST("Construct 4")
|
||||
{
|
||||
{
|
||||
test::random_values<T> v;
|
||||
T x(v.begin(), v.end(), 0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
test::random_values<T> v;
|
||||
T x(v.begin(), v.end(), 1);
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_SUB_TEST("Construct 5")
|
||||
{
|
||||
typename T::allocator_type al;
|
||||
|
||||
{
|
||||
T x(al);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_SUB_TEST("Construct 6")
|
||||
{
|
||||
typename T::allocator_type al;
|
||||
|
||||
T x(0, al);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
UNORDERED_SUB_TEST("Initializer list 1")
|
||||
{
|
||||
std::initializer_list<typename T::value_type> list;
|
||||
T x(list);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
UNORDERED_SUB_TEST("Initializer list 2")
|
||||
{
|
||||
{
|
||||
std::initializer_list<typename T::value_type> list;
|
||||
T x(list, 0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
std::initializer_list<typename T::value_type> list;
|
||||
T x(list, 1);
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void map_constructor_test(T*, test::random_generator const& generator)
|
||||
{
|
||||
@@ -394,6 +493,35 @@ namespace constructor_tests {
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_map;
|
||||
|
||||
UNORDERED_TEST(constructor_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(constructor_tests2,
|
||||
((test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(map_constructor_test,
|
||||
((test_map_std_alloc)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(no_alloc_default_construct_test,
|
||||
((test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
@@ -406,10 +534,6 @@ namespace constructor_tests {
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(constructor_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
@@ -422,11 +546,20 @@ namespace constructor_tests {
|
||||
((test_map_std_alloc)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(no_alloc_default_construct_test,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
UNORDERED_AUTO_TEST (test_default_initializer_list) {
|
||||
std::initializer_list<int> init;
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> x1 = init;
|
||||
#else
|
||||
boost::unordered_set<int> x1 = init;
|
||||
#endif
|
||||
BOOST_TEST(x1.empty());
|
||||
}
|
||||
|
||||
@@ -435,7 +568,12 @@ namespace constructor_tests {
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
UNORDERED_AUTO_TEST (test_initializer_list) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> x1 = {2, 10, 45, -5};
|
||||
#else
|
||||
boost::unordered_set<int> x1 = {2, 10, 45, -5};
|
||||
#endif
|
||||
|
||||
BOOST_TEST(x1.find(10) != x1.end());
|
||||
BOOST_TEST(x1.find(46) == x1.end());
|
||||
}
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
// Copyright 2021 Christian Mazakas.
|
||||
// Copyright 2021-2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
@@ -129,6 +124,20 @@ template <class UnorderedMap> void test_map_non_transparent_contains()
|
||||
|
||||
void test_map()
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_map<key, int, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
transparent_map;
|
||||
|
||||
typedef boost::unordered_flat_map<key, int, transparent_hasher, key_equal>
|
||||
non_transparent_map1;
|
||||
|
||||
typedef boost::unordered_flat_map<key, int, hasher, transparent_key_equal>
|
||||
non_transparent_map2;
|
||||
|
||||
typedef boost::unordered_flat_map<key, int, hasher, key_equal>
|
||||
non_transparent_map3;
|
||||
#else
|
||||
typedef boost::unordered_map<key, int, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
transparent_map;
|
||||
@@ -141,6 +150,7 @@ void test_map()
|
||||
|
||||
typedef boost::unordered_map<key, int, hasher, key_equal>
|
||||
non_transparent_map3;
|
||||
#endif
|
||||
|
||||
test_map_transparent_contains<transparent_map>();
|
||||
test_map_non_transparent_contains<non_transparent_map1>();
|
||||
@@ -148,6 +158,7 @@ void test_map()
|
||||
test_map_non_transparent_contains<non_transparent_map3>();
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
void test_multimap()
|
||||
{
|
||||
typedef boost::unordered_multimap<key, int, transparent_hasher,
|
||||
@@ -168,6 +179,7 @@ void test_multimap()
|
||||
test_map_non_transparent_contains<non_transparent_multimap2>();
|
||||
test_map_non_transparent_contains<non_transparent_multimap3>();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class UnorderedSet> void test_set_transparent_contains()
|
||||
{
|
||||
@@ -231,6 +243,18 @@ template <class UnorderedSet> void test_set_non_transparent_contains()
|
||||
|
||||
void test_set()
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<key, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
transparent_set;
|
||||
|
||||
typedef boost::unordered_flat_set<key, transparent_hasher, key_equal>
|
||||
non_transparent_set1;
|
||||
typedef boost::unordered_flat_set<key, hasher, transparent_key_equal>
|
||||
non_transparent_set2;
|
||||
typedef boost::unordered_flat_set<key, hasher, key_equal>
|
||||
non_transparent_set3;
|
||||
#else
|
||||
typedef boost::unordered_set<key, transparent_hasher, transparent_key_equal>
|
||||
transparent_set;
|
||||
|
||||
@@ -239,6 +263,7 @@ void test_set()
|
||||
typedef boost::unordered_set<key, hasher, transparent_key_equal>
|
||||
non_transparent_set2;
|
||||
typedef boost::unordered_set<key, hasher, key_equal> non_transparent_set3;
|
||||
#endif
|
||||
|
||||
test_set_transparent_contains<transparent_set>();
|
||||
test_set_non_transparent_contains<non_transparent_set1>();
|
||||
@@ -246,6 +271,7 @@ void test_set()
|
||||
test_set_non_transparent_contains<non_transparent_set3>();
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
void test_multiset()
|
||||
{
|
||||
typedef boost::unordered_multiset<key, transparent_hasher,
|
||||
@@ -264,11 +290,15 @@ void test_multiset()
|
||||
test_set_non_transparent_contains<non_transparent_multiset2>();
|
||||
test_set_non_transparent_contains<non_transparent_multiset3>();
|
||||
}
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (contains_) { // avoid -Wshadow warning with `bool contains`
|
||||
test_map();
|
||||
test_multimap();
|
||||
test_set();
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
test_multimap();
|
||||
test_multiset();
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
@@ -43,6 +39,23 @@ namespace copy_tests {
|
||||
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
BOOST_TEST(test::detail::tracker.count_allocations == 0);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
T x(0);
|
||||
T y(x);
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
BOOST_TEST(test::detail::tracker.count_allocations == 0);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
@@ -91,6 +104,22 @@ namespace copy_tests {
|
||||
|
||||
typedef typename T::allocator_type allocator_type;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
T x(0, hf, eq, al);
|
||||
T y(x);
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
BOOST_TEST(test::detail::tracker.count_allocations == 0);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -106,6 +135,21 @@ namespace copy_tests {
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
T x(0, hf, eq, al);
|
||||
T y(x, al2);
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) == 0);
|
||||
BOOST_TEST(test::detail::tracker.count_allocations == 0);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -120,6 +164,22 @@ namespace copy_tests {
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v;
|
||||
|
||||
T x(v.begin(), v.end(), 0, hf, eq, al);
|
||||
T y(x);
|
||||
test::unordered_equivalence_tester<T> equivalent(x);
|
||||
BOOST_TEST(equivalent(y));
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(test::detail::tracker.count_allocations == 0);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -135,6 +195,21 @@ namespace copy_tests {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v;
|
||||
|
||||
T x(v.begin(), v.end(), 0, hf, eq, al);
|
||||
T y(x, al2);
|
||||
test::unordered_equivalence_tester<T> equivalent(x);
|
||||
BOOST_TEST(equivalent(y));
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) == 0);
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
BOOST_TEST(test::detail::tracker.count_allocations == 0);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -150,6 +225,38 @@ namespace copy_tests {
|
||||
}
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_map;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
test_set_select_copy;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
test_map_select_copy;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
test_set_no_select_copy;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
test_map_no_select_copy;
|
||||
|
||||
UNORDERED_TEST(copy_construct_tests1,
|
||||
((test_set)(test_map)(test_set_select_copy)(test_map_select_copy)(test_set_no_select_copy)(test_map_no_select_copy))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(copy_construct_tests2,
|
||||
((test_set)(test_map)(test_set_select_copy)(test_map_select_copy)(test_set_no_select_copy)(test_map_no_select_copy))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
@@ -185,25 +292,14 @@ namespace copy_tests {
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
test_multimap_no_select_copy;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(copy_construct_tests1,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(
|
||||
test_multiset_select_copy)(test_map_select_copy)(
|
||||
test_multimap_select_copy)(test_set_no_select_copy)(
|
||||
test_multiset_no_select_copy)(test_map_no_select_copy)(
|
||||
test_multimap_no_select_copy))(
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(test_multiset_select_copy)(test_map_select_copy)(test_multimap_select_copy)(test_set_no_select_copy)(test_multiset_no_select_copy)(test_map_no_select_copy)(test_multimap_no_select_copy))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(copy_construct_tests2,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(
|
||||
test_multiset_select_copy)(test_map_select_copy)(
|
||||
test_multimap_select_copy)(test_set_no_select_copy)(
|
||||
test_multiset_no_select_copy)(test_map_no_select_copy)(
|
||||
test_multimap_no_select_copy))(
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(test_multiset_select_copy)(test_map_select_copy)(test_multimap_select_copy)(test_set_no_select_copy)(test_multiset_no_select_copy)(test_map_no_select_copy)(test_multimap_no_select_copy))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
}
|
||||
#endif
|
||||
} // namespace copy_tests
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
//
|
||||
// Copyright 2016 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -46,47 +42,56 @@ namespace emplace_tests {
|
||||
A8 a8;
|
||||
A9 a9;
|
||||
|
||||
emplace_value(A0 const& b0, A1 const& b1) : arg_count(2), a0(b0), a1(b1) {}
|
||||
emplace_value(A0 const& b0, A1 const& b1)
|
||||
: arg_count(2), a0(b0), a1(b1), a2('\0'), a3(-1), a4(-1), a5(-1),
|
||||
a6(-1), a7(-1), a8(-1), a9(-1)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2)
|
||||
: arg_count(3), a0(b0), a1(b1), a2(b2)
|
||||
: arg_count(3), a0(b0), a1(b1), a2(b2), a3(-1), a4(-1), a5(-1), a6(-1),
|
||||
a7(-1), a8(-1), a9(-1)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3)
|
||||
: arg_count(4), a0(b0), a1(b1), a2(b2), a3(b3)
|
||||
: arg_count(4), a0(b0), a1(b1), a2(b2), a3(b3), a4(-1), a5(-1), a6(-1),
|
||||
a7(-1), a8(-1), a9(-1)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(
|
||||
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4)
|
||||
: arg_count(5), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4)
|
||||
: arg_count(5), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(-1), a6(-1),
|
||||
a7(-1), a8(-1), a9(-1)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4, A5 const& b5)
|
||||
: arg_count(6), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5)
|
||||
: arg_count(6), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(-1),
|
||||
a7(-1), a8(-1), a9(-1)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4, A5 const& b5, A6 const& b6)
|
||||
: arg_count(7), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6)
|
||||
: arg_count(7), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
||||
a7(-1), a8(-1), a9(-1)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7)
|
||||
: arg_count(8), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
||||
a7(b7)
|
||||
a7(b7), a8(-1), a9(-1)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7, A8 const& b8)
|
||||
: arg_count(9), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
||||
a7(b7), a8(b8)
|
||||
a7(b7), a8(b8), a9(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -162,16 +167,29 @@ namespace emplace_tests {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
emplace_value() = delete;
|
||||
emplace_value(emplace_value const&) = default;
|
||||
emplace_value(emplace_value&&) = default;
|
||||
#else
|
||||
private:
|
||||
emplace_value();
|
||||
emplace_value(emplace_value const&);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST (emplace_set) {
|
||||
test::check_instances check_;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<emplace_value,
|
||||
boost::hash<emplace_value> >
|
||||
container;
|
||||
#else
|
||||
typedef boost::unordered_set<emplace_value, boost::hash<emplace_value> >
|
||||
container;
|
||||
#endif
|
||||
typedef container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
@@ -187,7 +205,15 @@ namespace emplace_tests {
|
||||
BOOST_TEST(*r1.first == v1);
|
||||
BOOST_TEST(r1.first == x.find(v1));
|
||||
BOOST_TEST_EQ(check_.instances(), 2);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
// 1 from v1
|
||||
// 1 from constructing the value_type() so we can pluck the key
|
||||
// 1 from move-constructing which invokes the counted_object base
|
||||
// constructor
|
||||
BOOST_TEST_EQ(check_.constructions(), 3);
|
||||
#else
|
||||
BOOST_TEST_EQ(check_.constructions(), 2);
|
||||
#endif
|
||||
|
||||
// 3 args
|
||||
|
||||
@@ -198,7 +224,11 @@ namespace emplace_tests {
|
||||
BOOST_TEST(*r1.first == v2);
|
||||
BOOST_TEST(r1.first == x.find(v2));
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||
#else
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
#endif
|
||||
|
||||
// 7 args with hint + duplicate
|
||||
|
||||
@@ -208,7 +238,11 @@ namespace emplace_tests {
|
||||
BOOST_TEST(*i1 == v3);
|
||||
BOOST_TEST(i1 == x.find(v3));
|
||||
BOOST_TEST_EQ(check_.instances(), 6);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST_EQ(check_.constructions(), 9);
|
||||
#else
|
||||
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||
#endif
|
||||
|
||||
r2 = x.emplace(25, "something", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
@@ -218,7 +252,11 @@ namespace emplace_tests {
|
||||
// whether it can emplace, so there's an extra construction
|
||||
// here.
|
||||
BOOST_TEST_EQ(check_.instances(), 6);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST_EQ(check_.constructions(), 10);
|
||||
#else
|
||||
BOOST_TEST_EQ(check_.constructions(), 7);
|
||||
#endif
|
||||
|
||||
// 10 args + hint duplicate
|
||||
|
||||
@@ -230,7 +268,11 @@ namespace emplace_tests {
|
||||
BOOST_TEST(*r1.first == v4);
|
||||
BOOST_TEST(r1.first == x.find(v4));
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST_EQ(check_.constructions(), 13);
|
||||
#else
|
||||
BOOST_TEST_EQ(check_.constructions(), 9);
|
||||
#endif
|
||||
|
||||
BOOST_TEST(
|
||||
r1.first == x.emplace_hint(r1.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||
@@ -239,7 +281,11 @@ namespace emplace_tests {
|
||||
BOOST_TEST(
|
||||
r1.first == x.emplace_hint(x.end(), 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST_EQ(check_.constructions(), 16);
|
||||
#else
|
||||
BOOST_TEST_EQ(check_.constructions(), 12);
|
||||
#endif
|
||||
|
||||
BOOST_TEST_EQ(x.size(), 4u);
|
||||
BOOST_TEST(x.count(v1) == 1);
|
||||
@@ -248,6 +294,7 @@ namespace emplace_tests {
|
||||
BOOST_TEST(x.count(v4) == 1);
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (emplace_multiset) {
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -325,20 +372,79 @@ namespace emplace_tests {
|
||||
BOOST_TEST_EQ(x.count(v2), 2u);
|
||||
BOOST_TEST_EQ(x.count(v3), 2u);
|
||||
}
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (emplace_map) {
|
||||
test::check_instances check_;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_map<emplace_value, emplace_value,
|
||||
boost::hash<emplace_value> >
|
||||
container;
|
||||
#else
|
||||
typedef boost::unordered_map<emplace_value, emplace_value,
|
||||
boost::hash<emplace_value> >
|
||||
container;
|
||||
#endif
|
||||
typedef container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
return_type r1, r2;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
// 5/8 args + duplicate
|
||||
emplace_value k1(5, "", 'b', 4, 5);
|
||||
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
r1 = x.emplace(std::piecewise_construct, std::make_tuple(5, "", 'b', 4, 5),
|
||||
std::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(x.find(k1) == r1.first);
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||
|
||||
r2 = x.emplace(std::piecewise_construct, std::make_tuple(5, "", 'b', 4, 5),
|
||||
std::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(!r2.second);
|
||||
BOOST_TEST(r1.first == r2.first);
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
// constructions could possibly be 5 if the implementation only
|
||||
// constructed the key.
|
||||
BOOST_TEST_EQ(check_.constructions(), 8);
|
||||
|
||||
// 9/3 args + duplicates with hints, different mapped value.
|
||||
|
||||
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
|
||||
emplace_value m2(3, "aaa", 'm');
|
||||
r1 = x.emplace(std::piecewise_construct,
|
||||
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
std::make_tuple(3, "aaa", 'm'));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(r1.first->first.arg_count == 9);
|
||||
BOOST_TEST(r1.first->second.arg_count == 3);
|
||||
BOOST_TEST(x.find(k2) == r1.first);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 14);
|
||||
|
||||
BOOST_TEST(r1.first == x.emplace_hint(r1.first, std::piecewise_construct,
|
||||
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
std::make_tuple(15, "jkjk")));
|
||||
BOOST_TEST(r1.first == x.emplace_hint(r2.first, std::piecewise_construct,
|
||||
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
std::make_tuple(275, "xxx", 'm', 6)));
|
||||
BOOST_TEST(r1.first == x.emplace_hint(x.end(), std::piecewise_construct,
|
||||
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
std::make_tuple(-10, "blah blah", '\0')));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 20);
|
||||
#else
|
||||
// 5/8 args + duplicate
|
||||
emplace_value k1(5, "", 'b', 4, 5);
|
||||
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
r1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
@@ -395,8 +501,10 @@ namespace emplace_tests {
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (emplace_multimap) {
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -461,11 +569,15 @@ namespace emplace_tests {
|
||||
BOOST_TEST_EQ(check_.instances(), 20);
|
||||
BOOST_TEST_EQ(check_.constructions(), 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (try_emplace) {
|
||||
test::check_instances check_;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_map<int, emplace_value> container;
|
||||
#else
|
||||
typedef boost::unordered_map<int, emplace_value> container;
|
||||
#endif
|
||||
typedef container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2008-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include <boost/preprocessor/seq.hpp>
|
||||
#include <list>
|
||||
@@ -30,14 +26,27 @@ namespace equality_tests {
|
||||
}
|
||||
};
|
||||
|
||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
using boost_unordered_set =
|
||||
boost::unordered_flat_set<int, mod_compare, mod_compare>;
|
||||
|
||||
using boost_unordered_map =
|
||||
boost::unordered_flat_map<int, int, mod_compare, mod_compare>;
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
}
|
||||
#else
|
||||
typedef boost::unordered_set<int, mod_compare, mod_compare>
|
||||
boost_unordered_set;
|
||||
|
||||
typedef boost::unordered_map<int, int, mod_compare, mod_compare>
|
||||
boost_unordered_map;
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
|
||||
@@ -46,17 +55,26 @@ namespace equality_tests {
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \
|
||||
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
|
||||
boost_unordered_set set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost_unordered_map map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
@@ -67,7 +85,11 @@ namespace equality_tests {
|
||||
map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
|
||||
|
||||
UNORDERED_AUTO_TEST (equality_size_tests) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> x1, x2;
|
||||
#else
|
||||
boost::unordered_set<int> x1, x2;
|
||||
#endif
|
||||
BOOST_TEST(x1 == x2);
|
||||
BOOST_TEST(!(x1 != x2));
|
||||
|
||||
@@ -134,7 +156,7 @@ namespace equality_tests {
|
||||
// different hash functions but the same equality predicate.
|
||||
|
||||
UNORDERED_AUTO_TEST (equality_different_hash_test) {
|
||||
typedef boost::unordered_set<int, mod_compare, mod_compare> set;
|
||||
typedef boost_unordered_set set;
|
||||
set set1(0, mod_compare(false), mod_compare(false));
|
||||
set set2(0, mod_compare(true), mod_compare(true));
|
||||
BOOST_TEST(set1 == set2);
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include <algorithm>
|
||||
@@ -38,8 +34,11 @@ void test_equal_insertion(Iterator begin, Iterator end)
|
||||
UNORDERED_AUTO_TEST (set_tests) {
|
||||
int values[][5] = {{1}, {54, 23}, {-13, 65}, {77, 77}, {986, 25, 986}};
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int> set;
|
||||
#else
|
||||
typedef boost::unordered_set<int> set;
|
||||
typedef boost::unordered_multiset<int> multiset;
|
||||
#endif
|
||||
|
||||
test_equal_insertion<set>(values[0], values[0] + 1);
|
||||
test_equal_insertion<set>(values[1], values[1] + 2);
|
||||
@@ -47,6 +46,7 @@ UNORDERED_AUTO_TEST (set_tests) {
|
||||
test_equal_insertion<set>(values[3], values[3] + 2);
|
||||
test_equal_insertion<set>(values[4], values[4] + 3);
|
||||
|
||||
typedef boost::unordered_multiset<int> multiset;
|
||||
test_equal_insertion<multiset>(values[0], values[0] + 1);
|
||||
test_equal_insertion<multiset>(values[1], values[1] + 2);
|
||||
test_equal_insertion<multiset>(values[2], values[2] + 2);
|
||||
@@ -66,12 +66,17 @@ UNORDERED_AUTO_TEST (map_tests) {
|
||||
v[2].push_back(std::pair<int const, int>(432, 24));
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
test_equal_insertion<boost::unordered_flat_map<int, int> >(
|
||||
v[i].begin(), v[i].end());
|
||||
#else
|
||||
test_equal_insertion<boost::unordered_map<int, int> >(
|
||||
v[i].begin(), v[i].end());
|
||||
|
||||
for (int i2 = 0; i2 < 5; ++i2)
|
||||
test_equal_insertion<boost::unordered_multimap<int, int> >(
|
||||
v[i2].begin(), v[i2].end());
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
@@ -23,36 +18,13 @@
|
||||
namespace test {
|
||||
struct is_even
|
||||
{
|
||||
is_even() {}
|
||||
|
||||
#if BOOST_CXX_VERSION >= 201703L
|
||||
// immovable for C++17
|
||||
is_even(is_even const&) = delete;
|
||||
is_even(is_even&&) = delete;
|
||||
|
||||
is_even& operator=(is_even const&) = delete;
|
||||
is_even& operator=(is_even&&) = delete;
|
||||
#elif BOOST_CXX_VERSION >= 201103L
|
||||
// move-only for C++11
|
||||
is_even(is_even const&) = delete;
|
||||
is_even(is_even&&) = default;
|
||||
|
||||
is_even& operator=(is_even const&) = delete;
|
||||
is_even& operator=(is_even&&) = default;
|
||||
#else
|
||||
// copyable otherwise
|
||||
is_even(is_even const&) {}
|
||||
is_even& operator=(is_even const&) { return *this; }
|
||||
#endif
|
||||
|
||||
bool operator()(
|
||||
std::pair<std::string const, int>& key_value) UNORDERED_LVALUE_QUAL
|
||||
bool operator()(std::pair<std::string const, int>& key_value)
|
||||
{
|
||||
int const v = key_value.second;
|
||||
return (v % 2 == 0);
|
||||
}
|
||||
|
||||
bool operator()(int const& value) UNORDERED_LVALUE_QUAL
|
||||
bool operator()(int const& value)
|
||||
{
|
||||
int const v = value;
|
||||
return (v % 2 == 0);
|
||||
@@ -61,37 +33,13 @@ namespace test {
|
||||
|
||||
struct is_too_large
|
||||
{
|
||||
is_too_large() {}
|
||||
|
||||
#if BOOST_CXX_VERSION >= 201703L
|
||||
// immovable for C++17
|
||||
is_too_large(is_too_large const&) = delete;
|
||||
is_too_large(is_too_large&&) = delete;
|
||||
|
||||
is_too_large& operator=(is_too_large const&) = delete;
|
||||
is_too_large& operator=(is_too_large&&) = delete;
|
||||
#elif BOOST_CXX_VERSION >= 201103L
|
||||
// move-only for C++11
|
||||
is_too_large(is_too_large const&) = delete;
|
||||
is_too_large(is_too_large&&) = default;
|
||||
|
||||
is_too_large& operator=(is_too_large const&) = delete;
|
||||
is_too_large& operator=(is_too_large&&) = default;
|
||||
#else
|
||||
// copyable otherwise
|
||||
is_too_large(is_too_large const&) {}
|
||||
|
||||
is_too_large& operator=(is_too_large const&) { return *this; }
|
||||
#endif
|
||||
|
||||
bool operator()(
|
||||
std::pair<std::string const, int>& key_value) UNORDERED_LVALUE_QUAL
|
||||
bool operator()(std::pair<std::string const, int>& key_value)
|
||||
{
|
||||
int const v = key_value.second;
|
||||
return v >= 1000;
|
||||
}
|
||||
|
||||
bool operator()(int const& value) UNORDERED_LVALUE_QUAL
|
||||
bool operator()(int const& value)
|
||||
{
|
||||
int const v = value;
|
||||
return v >= 1000;
|
||||
@@ -159,11 +107,16 @@ template <class UnorderedSet> void test_set_erase_if()
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (unordered_erase_if) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
test_map_erase_if<boost::unordered_flat_map<std::string, int> >();
|
||||
test_set_erase_if<boost::unordered_flat_set<int> >();
|
||||
#else
|
||||
test_map_erase_if<boost::unordered_map<std::string, int> >();
|
||||
test_map_erase_if<boost::unordered_multimap<std::string, int> >();
|
||||
|
||||
test_set_erase_if<boost::unordered_set<int> >();
|
||||
test_set_erase_if<boost::unordered_multiset<int> >();
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
@@ -27,7 +23,9 @@ namespace erase_tests {
|
||||
template <class Container>
|
||||
void erase_tests1(Container*, test::random_generator generator)
|
||||
{
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename Container::iterator iterator;
|
||||
#endif
|
||||
typedef typename Container::const_iterator c_iterator;
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Erase by key.\n";
|
||||
@@ -61,9 +59,13 @@ namespace erase_tests {
|
||||
while (size > 0 && !x.empty()) {
|
||||
typename Container::key_type key = test::get_key<Container>(*x.begin());
|
||||
std::size_t count = x.count(key);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
x.erase(x.begin());
|
||||
#else
|
||||
iterator pos = x.erase(x.begin());
|
||||
--size;
|
||||
BOOST_TEST(pos == x.begin());
|
||||
#endif
|
||||
--size;
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
BOOST_TEST(x.size() == size);
|
||||
if (++iterations % 20 == 0)
|
||||
@@ -93,10 +95,15 @@ namespace erase_tests {
|
||||
typename Container::key_type key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_TEST(count > 0);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
x.erase(pos);
|
||||
--size;
|
||||
#else
|
||||
BOOST_TEST(next == x.erase(pos));
|
||||
--size;
|
||||
if (size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() : next == test::next(prev));
|
||||
#endif
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
if (x.count(key) != count - 1) {
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << count << " => " << x.count(key)
|
||||
@@ -185,7 +192,11 @@ namespace erase_tests {
|
||||
while (size > 0 && !x.empty()) {
|
||||
typename Container::key_type key = test::get_key<Container>(*x.begin());
|
||||
std::size_t count = x.count(key);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
x.erase(x.begin());
|
||||
#else
|
||||
x.quick_erase(x.begin());
|
||||
#endif
|
||||
--size;
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
BOOST_TEST(x.size() == size);
|
||||
@@ -216,7 +227,11 @@ namespace erase_tests {
|
||||
typename Container::key_type key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_TEST(count > 0);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
x.erase(pos);
|
||||
#else
|
||||
x.quick_erase(pos);
|
||||
#endif
|
||||
--size;
|
||||
if (size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() : next == test::next(prev));
|
||||
@@ -246,6 +261,20 @@ namespace erase_tests {
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "\n";
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_map;
|
||||
|
||||
UNORDERED_TEST(
|
||||
erase_tests1, ((test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
@@ -255,13 +284,11 @@ namespace erase_tests {
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(
|
||||
erase_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
@@ -133,6 +129,20 @@ namespace find_tests {
|
||||
}
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_map;
|
||||
|
||||
UNORDERED_TEST(
|
||||
find_tests1, ((test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
@@ -142,16 +152,13 @@ namespace find_tests {
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(
|
||||
find_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(find_compatible_keys_test,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,14 +1,44 @@
|
||||
|
||||
// Copyright 2008-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
#include <boost/unordered/unordered_flat_map_fwd.hpp>
|
||||
#include <boost/unordered/detail/implementation.hpp>
|
||||
#else
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
#endif
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
template <typename T>
|
||||
void call_swap(
|
||||
boost::unordered_flat_map<T, T>& x, boost::unordered_flat_map<T, T>& y)
|
||||
{
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_equals(
|
||||
boost::unordered_flat_map<T, T>& x, boost::unordered_flat_map<T, T>& y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_not_equals(
|
||||
boost::unordered_flat_map<T, T>& x, boost::unordered_flat_map<T, T>& y)
|
||||
{
|
||||
return x != y;
|
||||
}
|
||||
|
||||
#include <boost/unordered/unordered_flat_map.hpp>
|
||||
#else
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
|
||||
{
|
||||
@@ -50,10 +80,15 @@ bool call_not_equals(
|
||||
}
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#endif
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_map<int, int> int_map;
|
||||
#else
|
||||
typedef boost::unordered_map<int, int> int_map;
|
||||
typedef boost::unordered_multimap<int, int> int_multimap;
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (use_map_fwd_declared_function) {
|
||||
int_map x, y;
|
||||
@@ -71,11 +106,13 @@ UNORDERED_AUTO_TEST (use_map_fwd_declared_function) {
|
||||
BOOST_TEST(call_not_equals(x, y));
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (use_multimap_fwd_declared_function) {
|
||||
int_multimap x, y;
|
||||
call_swap(x, y);
|
||||
BOOST_TEST(call_equals(x, y));
|
||||
BOOST_TEST(!call_not_equals(x, y));
|
||||
}
|
||||
#endif
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
|
||||
// Copyright 2008-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
#include <boost/unordered/unordered_flat_set_fwd.hpp>
|
||||
#include <boost/unordered/detail/implementation.hpp>
|
||||
#else
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
#endif
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
|
||||
@@ -20,6 +26,31 @@ struct false_type
|
||||
|
||||
false_type is_unordered_set_impl(void*);
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
template <class Value, class Hash, class Pred, class Alloc>
|
||||
true_type is_unordered_set_impl(
|
||||
boost::unordered_flat_set<Value, Hash, Pred, Alloc>*);
|
||||
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_flat_set<T>& x, boost::unordered_flat_set<T>& y)
|
||||
{
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_equals(
|
||||
boost::unordered_flat_set<T>& x, boost::unordered_flat_set<T>& y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_not_equals(
|
||||
boost::unordered_flat_set<T>& x, boost::unordered_flat_set<T>& y)
|
||||
{
|
||||
return x != y;
|
||||
}
|
||||
#else
|
||||
template <class Value, class Hash, class Pred, class Alloc>
|
||||
true_type is_unordered_set_impl(
|
||||
boost::unordered_set<Value, Hash, Pred, Alloc>*);
|
||||
@@ -41,7 +72,9 @@ bool call_not_equals(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
|
||||
{
|
||||
return x != y;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
|
||||
{
|
||||
@@ -61,20 +94,29 @@ bool call_not_equals(
|
||||
{
|
||||
return x != y;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int> int_set;
|
||||
#else
|
||||
typedef boost::unordered_set<int> int_set;
|
||||
typedef boost::unordered_multiset<int> int_multiset;
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (use_fwd_declared_trait_without_definition) {
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*)0)) == sizeof(true_type));
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
#include <boost/unordered/unordered_flat_set.hpp>
|
||||
#else
|
||||
#include <boost/unordered_set.hpp>
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (use_fwd_declared_trait) {
|
||||
boost::unordered_set<int> x;
|
||||
int_set x;
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
|
||||
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int*)0)) == sizeof(false_type));
|
||||
@@ -96,11 +138,13 @@ UNORDERED_AUTO_TEST (use_set_fwd_declared_function) {
|
||||
BOOST_TEST(call_not_equals(x, y));
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (use_multiset_fwd_declared_function) {
|
||||
int_multiset x, y;
|
||||
call_swap(x, y);
|
||||
BOOST_TEST(call_equals(x, y));
|
||||
BOOST_TEST(!call_not_equals(x, y));
|
||||
}
|
||||
#endif
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
|
||||
// Copyright 2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace x {
|
||||
struct D
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<D, D> x;
|
||||
#else
|
||||
boost::unordered_map<D, D> x;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,6 +29,17 @@ namespace incomplete_test {
|
||||
|
||||
// Declare some instances
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_map<value, value, hash, equals,
|
||||
allocator<std::pair<value const, value> > >
|
||||
map;
|
||||
typedef boost::unordered_flat_map<value, value, hash, equals,
|
||||
allocator<std::pair<value const, value> > >
|
||||
multimap;
|
||||
typedef boost::unordered_flat_set<value, hash, equals, allocator<value> > set;
|
||||
typedef boost::unordered_flat_set<value, hash, equals, allocator<value> >
|
||||
multiset;
|
||||
#else
|
||||
typedef boost::unordered_map<value, value, hash, equals,
|
||||
allocator<std::pair<value const, value> > >
|
||||
map;
|
||||
@@ -38,6 +49,7 @@ namespace incomplete_test {
|
||||
typedef boost::unordered_set<value, hash, equals, allocator<value> > set;
|
||||
typedef boost::unordered_multiset<value, hash, equals, allocator<value> >
|
||||
multiset;
|
||||
#endif
|
||||
|
||||
// Now define the types which are stored as members, as they are needed for
|
||||
// declaring struct members.
|
||||
@@ -76,7 +88,28 @@ namespace incomplete_test {
|
||||
//
|
||||
// Incomplete hash, equals and allocator aren't here supported at the
|
||||
// moment.
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
struct struct1
|
||||
{
|
||||
boost::unordered_flat_map<struct1, struct1, hash, equals,
|
||||
allocator<std::pair<struct1 const, struct1> > >
|
||||
x;
|
||||
};
|
||||
struct struct2
|
||||
{
|
||||
boost::unordered_flat_map<struct2, struct2, hash, equals,
|
||||
allocator<std::pair<struct2 const, struct2> > >
|
||||
x;
|
||||
};
|
||||
struct struct3
|
||||
{
|
||||
boost::unordered_flat_set<struct3, hash, equals, allocator<struct3> > x;
|
||||
};
|
||||
struct struct4
|
||||
{
|
||||
boost::unordered_flat_set<struct4, hash, equals, allocator<struct4> > x;
|
||||
};
|
||||
#else
|
||||
struct struct1
|
||||
{
|
||||
boost::unordered_map<struct1, struct1, hash, equals,
|
||||
@@ -97,7 +130,7 @@ namespace incomplete_test {
|
||||
{
|
||||
boost::unordered_multiset<struct4, hash, equals, allocator<struct4> > x;
|
||||
};
|
||||
|
||||
#endif
|
||||
// Now define the value type.
|
||||
|
||||
struct value
|
||||
|
||||
244
test/unordered/init_type_insert_tests.cpp
Normal file
244
test/unordered/init_type_insert_tests.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_UNORDERED_FOA_TESTS)
|
||||
#error "This test is only for the FOA-style conatiners"
|
||||
#endif
|
||||
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
struct move_only
|
||||
{
|
||||
int x_ = -1;
|
||||
|
||||
move_only() = default;
|
||||
move_only(int x) : x_{x} {}
|
||||
move_only(move_only const&) = delete;
|
||||
move_only(move_only&&) = default;
|
||||
|
||||
friend bool operator==(move_only const& lhs, move_only const& rhs)
|
||||
{
|
||||
return lhs.x_ == rhs.x_;
|
||||
}
|
||||
};
|
||||
|
||||
namespace std{
|
||||
|
||||
template <> struct hash<move_only>
|
||||
{
|
||||
std::size_t operator()(move_only const& mo) const noexcept
|
||||
{
|
||||
return std::hash<int>()(mo.x_);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
struct raii_tracker
|
||||
{
|
||||
static unsigned move_constructs;
|
||||
static unsigned copy_constructs;
|
||||
|
||||
int x_ = -1;
|
||||
|
||||
static void reset_counts()
|
||||
{
|
||||
move_constructs = 0;
|
||||
copy_constructs = 0;
|
||||
}
|
||||
|
||||
raii_tracker() {}
|
||||
raii_tracker(int x) : x_{x} {}
|
||||
raii_tracker(raii_tracker const& rhs) : x_{rhs.x_} { ++copy_constructs; }
|
||||
|
||||
raii_tracker(raii_tracker&& rhs) noexcept : x_{rhs.x_}
|
||||
{
|
||||
rhs.x_ = -1;
|
||||
|
||||
++move_constructs;
|
||||
}
|
||||
|
||||
friend bool operator==(raii_tracker const& lhs, raii_tracker const& rhs)
|
||||
{
|
||||
return lhs.x_ == rhs.x_;
|
||||
}
|
||||
};
|
||||
|
||||
namespace std{
|
||||
|
||||
template <> struct hash<raii_tracker>
|
||||
{
|
||||
std::size_t operator()(raii_tracker const& rt) const noexcept
|
||||
{
|
||||
return std::hash<int>()(rt.x_);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
unsigned raii_tracker::move_constructs = 0;
|
||||
unsigned raii_tracker::copy_constructs = 0;
|
||||
|
||||
static void test_move_only()
|
||||
{
|
||||
int const v = 128;
|
||||
|
||||
boost::unordered_flat_map<move_only, int, std::hash<move_only> > map;
|
||||
|
||||
using init_type = decltype(map)::init_type;
|
||||
static_assert(
|
||||
std::is_same<decltype(std::make_pair(move_only(1), v)), init_type>::value,
|
||||
"");
|
||||
|
||||
map.insert(std::make_pair(move_only(1), v));
|
||||
map.insert({move_only(2), v});
|
||||
|
||||
BOOST_TEST_EQ(map.size(), 2u);
|
||||
|
||||
map.rehash(1024);
|
||||
BOOST_TEST_GE(map.bucket_count(), 1024u);
|
||||
}
|
||||
|
||||
static void test_insert_tracking()
|
||||
{
|
||||
raii_tracker::reset_counts();
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 0u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 0u);
|
||||
|
||||
boost::unordered_flat_map<raii_tracker, raii_tracker,
|
||||
std::hash<raii_tracker> >
|
||||
map;
|
||||
|
||||
{
|
||||
std::pair<raii_tracker, raii_tracker> value{1, 2};
|
||||
|
||||
map.insert(value);
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<raii_tracker, raii_tracker> value{2, 3};
|
||||
|
||||
map.insert(std::move(value));
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 2u);
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<raii_tracker const, raii_tracker> value{3, 4};
|
||||
|
||||
map.insert(value);
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 4u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 2u);
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<raii_tracker const, raii_tracker> value{4, 5};
|
||||
|
||||
map.insert(std::move(value));
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 3u);
|
||||
}
|
||||
|
||||
{
|
||||
map.insert(std::make_pair(5, 6));
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 5u);
|
||||
}
|
||||
|
||||
{
|
||||
map.insert({6, 7});
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 7u);
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(map.size(), 6u);
|
||||
|
||||
map.rehash(1024);
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 7u + 2u * map.size());
|
||||
}
|
||||
|
||||
static void test_insert_hint_tracking()
|
||||
{
|
||||
raii_tracker::reset_counts();
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 0u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 0u);
|
||||
|
||||
boost::unordered_flat_map<raii_tracker, raii_tracker,
|
||||
std::hash<raii_tracker> >
|
||||
map;
|
||||
|
||||
{
|
||||
std::pair<raii_tracker, raii_tracker> value{1, 2};
|
||||
|
||||
map.insert(map.begin(), value);
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<raii_tracker, raii_tracker> value{2, 3};
|
||||
|
||||
map.insert(std::move(value));
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 2u);
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<raii_tracker const, raii_tracker> value{3, 4};
|
||||
|
||||
map.insert(map.begin(), value);
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 4u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 2u);
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<raii_tracker const, raii_tracker> value{4, 5};
|
||||
|
||||
map.insert(map.begin(), std::move(value));
|
||||
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 3u);
|
||||
}
|
||||
|
||||
{
|
||||
map.insert(map.begin(), std::make_pair(5, 6));
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 5u);
|
||||
}
|
||||
|
||||
{
|
||||
map.insert(map.begin(), {6, 7});
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 7u);
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(map.size(), 6u);
|
||||
|
||||
map.rehash(1024);
|
||||
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||
BOOST_TEST_EQ(raii_tracker::move_constructs, 7u + 2u * map.size());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_move_only();
|
||||
test_insert_tracking();
|
||||
test_insert_hint_tracking();
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2016 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
@@ -17,6 +13,7 @@
|
||||
#include <set>
|
||||
|
||||
namespace insert_hint {
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (insert_hint_empty) {
|
||||
typedef boost::unordered_multiset<int> container;
|
||||
container x;
|
||||
@@ -90,9 +87,13 @@ namespace insert_hint {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
UNORDERED_AUTO_TEST (insert_hint_unique) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int> container;
|
||||
#else
|
||||
typedef boost::unordered_set<int> container;
|
||||
#endif
|
||||
container x;
|
||||
x.insert(x.cbegin(), 10);
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
@@ -101,7 +102,11 @@ namespace insert_hint {
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (insert_hint_unique_single) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int> container;
|
||||
#else
|
||||
typedef boost::unordered_set<int> container;
|
||||
#endif
|
||||
container x;
|
||||
x.insert(10);
|
||||
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
|
||||
// Copyright 2006-2010 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(PIECEWISE_TEST_NAME)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
@@ -21,6 +17,8 @@
|
||||
#include "../helpers/input_iterator.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace insert_tests {
|
||||
|
||||
test::seed_t initialize_seed(243432);
|
||||
@@ -678,6 +676,23 @@ namespace insert_tests {
|
||||
}
|
||||
}
|
||||
|
||||
template <class X> void set_tests(X*, test::random_generator)
|
||||
{
|
||||
// prove that our insert(iterator, iterator) implementation honors
|
||||
// Cpp17EmplaceConstructible
|
||||
//
|
||||
|
||||
X x;
|
||||
std::vector<int> v;
|
||||
v.reserve(1000);
|
||||
for (unsigned i = 0; i < 1000; ++i) {
|
||||
v.push_back(static_cast<int>(i));
|
||||
}
|
||||
|
||||
x.insert(v.begin(), v.end());
|
||||
BOOST_TEST_EQ(x.size(), 1000u);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void try_emplace_tests(X*, test::random_generator generator)
|
||||
{
|
||||
@@ -870,6 +885,53 @@ namespace insert_tests {
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::movable, test::hash, test::equal_to,
|
||||
std::allocator<test::movable> >* test_set_std_alloc;
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::movable, test::movable, test::hash,
|
||||
test::equal_to, test::allocator2<test::movable> >* test_map;
|
||||
|
||||
UNORDERED_TEST(unique_insert_tests1,
|
||||
((test_set_std_alloc)(test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(
|
||||
insert_tests2, ((test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(unique_emplace_tests1,
|
||||
((test_set_std_alloc)(test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(move_emplace_tests,
|
||||
((test_set_std_alloc)(test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(default_emplace_tests,
|
||||
((test_set_std_alloc)(test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(map_tests,
|
||||
((test_map))((default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(
|
||||
map_tests2, ((test_map))((default_generator)(generate_collisions)))
|
||||
|
||||
UNORDERED_TEST(map_insert_range_test1,
|
||||
((test_map))((default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(map_insert_range_test2,
|
||||
((test_map))((default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(
|
||||
set_tests, ((test_set_std_alloc)(test_set))((default_generator)))
|
||||
#else
|
||||
boost::unordered_set<test::movable, test::hash, test::equal_to,
|
||||
std::allocator<test::movable> >* test_set_std_alloc;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
@@ -884,10 +946,6 @@ namespace insert_tests {
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(unique_insert_tests1,
|
||||
((test_set_std_alloc)(test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
@@ -897,8 +955,8 @@ namespace insert_tests {
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(insert_tests2,
|
||||
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(
|
||||
test_multimap))((default_generator)(generate_collisions)(limited_range)))
|
||||
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(unique_emplace_tests1,
|
||||
((test_set_std_alloc)(test_set)(test_map))(
|
||||
@@ -909,13 +967,11 @@ namespace insert_tests {
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(move_emplace_tests,
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
|
||||
test_multiset)(test_multimap))(
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(test_multiset)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(default_emplace_tests,
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
|
||||
test_multiset)(test_multimap))(
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(test_multiset)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(map_tests,
|
||||
@@ -932,6 +988,10 @@ namespace insert_tests {
|
||||
((test_multimap_std_alloc)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(
|
||||
set_tests, ((test_set_std_alloc)(test_set)(test_multiset))((default_generator)))
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
struct initialize_from_two_ints
|
||||
@@ -950,13 +1010,21 @@ namespace insert_tests {
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST (insert_initializer_list_set) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> set;
|
||||
#else
|
||||
boost::unordered_set<int> set;
|
||||
#endif
|
||||
set.insert({1, 2, 3, 1});
|
||||
BOOST_TEST_EQ(set.size(), 3u);
|
||||
BOOST_TEST(set.find(1) != set.end());
|
||||
BOOST_TEST(set.find(4) == set.end());
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<initialize_from_two_ints> set2;
|
||||
#else
|
||||
boost::unordered_set<initialize_from_two_ints> set2;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))
|
||||
set2.insert({{1, 2}});
|
||||
@@ -985,6 +1053,7 @@ namespace insert_tests {
|
||||
BOOST_TEST(set2.find({8, 7}) == set2.end());
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
|
||||
|
||||
UNORDERED_AUTO_TEST (insert_initializer_list_multiset) {
|
||||
@@ -1002,16 +1071,22 @@ namespace insert_tests {
|
||||
BOOST_TEST_EQ(multiset.count("c"), 0u);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (insert_initializer_list_map) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<std::string, std::string> map;
|
||||
#else
|
||||
boost::unordered_map<std::string, std::string> map;
|
||||
#endif
|
||||
// map.insert({});
|
||||
BOOST_TEST(map.empty());
|
||||
map.insert({{"a", "b"}, {"a", "b"}, {"d", ""}});
|
||||
BOOST_TEST_EQ(map.size(), 2u);
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (insert_initializer_list_multimap) {
|
||||
boost::unordered_multimap<std::string, std::string> multimap;
|
||||
// multimap.insert({});
|
||||
@@ -1020,6 +1095,7 @@ namespace insert_tests {
|
||||
BOOST_TEST_EQ(multimap.size(), 3u);
|
||||
BOOST_TEST_EQ(multimap.count("a"), 2u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1050,10 +1126,18 @@ namespace insert_tests {
|
||||
|
||||
UNORDERED_AUTO_TEST (map_emplace_test) {
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<int, overloaded_constructor, test::hash,
|
||||
test::equal_to,
|
||||
test::allocator1<std::pair<int const, overloaded_constructor> > >
|
||||
x;
|
||||
#else
|
||||
|
||||
boost::unordered_map<int, overloaded_constructor, test::hash,
|
||||
test::equal_to,
|
||||
test::allocator1<std::pair<int const, overloaded_constructor> > >
|
||||
x;
|
||||
#endif
|
||||
|
||||
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
|
||||
x.emplace();
|
||||
@@ -1070,6 +1154,7 @@ namespace insert_tests {
|
||||
x.find(5) != x.end() && x.find(5)->second == overloaded_constructor());
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
{
|
||||
boost::unordered_multimap<int, overloaded_constructor, test::hash,
|
||||
test::equal_to,
|
||||
@@ -1086,11 +1171,17 @@ namespace insert_tests {
|
||||
BOOST_TEST(
|
||||
x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (set_emplace_test) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<overloaded_constructor> x;
|
||||
overloaded_constructor check;
|
||||
#else
|
||||
boost::unordered_set<overloaded_constructor> x;
|
||||
overloaded_constructor check;
|
||||
#endif
|
||||
|
||||
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
|
||||
x.emplace();
|
||||
@@ -1136,6 +1227,7 @@ namespace insert_tests {
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (map_emplace_test2) {
|
||||
// Emulating piecewise construction with boost::tuple bypasses the
|
||||
// allocator's construct method, but still uses test destroy method.
|
||||
@@ -1259,10 +1351,13 @@ namespace insert_tests {
|
||||
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
|
||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Use the preprocessor to generate tests using different combinations of
|
||||
// boost/std piecewise_construct_t/tuple.
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
|
||||
#define PIECEWISE_TEST_NAME boost_tuple_piecewise_tests
|
||||
#define PIECEWISE_NAMESPACE boost::unordered
|
||||
#define TUPLE_NAMESPACE boost
|
||||
@@ -1289,6 +1384,8 @@ namespace insert_tests {
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
|
||||
BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
|
||||
@@ -1311,12 +1408,21 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(BOOST_UNORDERED_FOA_TESTS)
|
||||
boost::unordered_flat_map<overloaded_constructor, overloaded_constructor,
|
||||
boost::hash<overloaded_constructor>,
|
||||
std::equal_to<overloaded_constructor>,
|
||||
test::allocator1<
|
||||
std::pair<overloaded_constructor const, overloaded_constructor> > >
|
||||
x;
|
||||
#else
|
||||
boost::unordered_map<overloaded_constructor, overloaded_constructor,
|
||||
boost::hash<overloaded_constructor>,
|
||||
std::equal_to<overloaded_constructor>,
|
||||
test::allocator1<
|
||||
std::pair<overloaded_constructor const, overloaded_constructor> > >
|
||||
x;
|
||||
#endif
|
||||
|
||||
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
|
||||
TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple());
|
||||
@@ -1360,6 +1466,7 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
|
||||
x.find(overloaded_constructor(2, 3))->second ==
|
||||
overloaded_constructor(4, 5, 6));
|
||||
}
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
{
|
||||
boost::unordered_multimap<overloaded_constructor, overloaded_constructor,
|
||||
boost::hash<overloaded_constructor>,
|
||||
@@ -1393,6 +1500,7 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
|
||||
x.find(overloaded_constructor(9, 3, 1))->second ==
|
||||
overloaded_constructor(10));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) {
|
||||
@@ -1400,9 +1508,15 @@ UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) {
|
||||
test::detail::disable_construction_tracking _scoped;
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<
|
||||
std::pair<overloaded_constructor, overloaded_constructor> >
|
||||
x;
|
||||
#else
|
||||
boost::unordered_set<
|
||||
std::pair<overloaded_constructor, overloaded_constructor> >
|
||||
x;
|
||||
#endif
|
||||
std::pair<overloaded_constructor, overloaded_constructor> check;
|
||||
|
||||
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
void foo(boost::unordered_flat_set<int>&, boost::unordered_flat_map<int, int>&);
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::unordered_flat_set<int> x1;
|
||||
boost::unordered_flat_map<int, int> x2;
|
||||
|
||||
foo(x1, x2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
void foo(boost::unordered_set<int>&, boost::unordered_map<int, int>&,
|
||||
boost::unordered_multiset<int>&, boost::unordered_multimap<int, int>&);
|
||||
|
||||
@@ -24,3 +33,4 @@ int main()
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
void foo(
|
||||
boost::unordered_flat_set<int>& x1, boost::unordered_flat_map<int, int>& x2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy
|
||||
{
|
||||
boost::unordered_flat_set<int> x1;
|
||||
boost::unordered_flat_map<int, int> x2;
|
||||
};
|
||||
#endif
|
||||
|
||||
x1.insert(1);
|
||||
x2[2] = 2;
|
||||
}
|
||||
#else
|
||||
void foo(boost::unordered_set<int>& x1, boost::unordered_map<int, int>& x2,
|
||||
boost::unordered_multiset<int>& x3, boost::unordered_multimap<int, int>& x4)
|
||||
{
|
||||
@@ -28,3 +40,4 @@ void foo(boost::unordered_set<int>& x1, boost::unordered_map<int, int>& x2,
|
||||
x3.insert(3);
|
||||
x4.insert(std::make_pair(4, 5));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include <boost/limits.hpp>
|
||||
@@ -26,7 +22,17 @@ namespace load_factor_tests {
|
||||
template <class X> void set_load_factor_tests(X*)
|
||||
{
|
||||
X x;
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(x.max_load_factor() == boost::unordered::detail::foa::mlf);
|
||||
BOOST_TEST(x.load_factor() == 0);
|
||||
|
||||
// A valid implementation could fail these tests, but I think they're
|
||||
// reasonable.
|
||||
x.max_load_factor(2.0);
|
||||
BOOST_TEST(x.max_load_factor() == boost::unordered::detail::foa::mlf);
|
||||
x.max_load_factor(0.5);
|
||||
BOOST_TEST(x.max_load_factor() == boost::unordered::detail::foa::mlf);
|
||||
#else
|
||||
BOOST_TEST(x.max_load_factor() == 1.0);
|
||||
BOOST_TEST(x.load_factor() == 0);
|
||||
|
||||
@@ -36,6 +42,7 @@ namespace load_factor_tests {
|
||||
BOOST_TEST(x.max_load_factor() == 2.0);
|
||||
x.max_load_factor(0.5);
|
||||
BOOST_TEST(x.max_load_factor() == 0.5);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X>
|
||||
@@ -72,21 +79,32 @@ namespace load_factor_tests {
|
||||
insert_test(ptr, std::numeric_limits<float>::infinity(), generator);
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int>* int_set_ptr;
|
||||
boost::unordered_flat_map<int, int>* int_map_ptr;
|
||||
|
||||
UNORDERED_TEST(set_load_factor_tests, ((int_set_ptr)(int_map_ptr)))
|
||||
|
||||
UNORDERED_TEST(load_factor_insert_tests,
|
||||
((int_set_ptr)(int_map_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_set<int>* int_set_ptr;
|
||||
boost::unordered_multiset<int>* int_multiset_ptr;
|
||||
boost::unordered_map<int, int>* int_map_ptr;
|
||||
boost::unordered_multimap<int, int>* int_multimap_ptr;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(set_load_factor_tests,
|
||||
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr)))
|
||||
|
||||
UNORDERED_TEST(load_factor_insert_tests,
|
||||
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
|
||||
// Copyright 2016 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "../helpers/postfix.hpp"
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/count.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
@@ -19,8 +17,13 @@
|
||||
namespace merge_tests {
|
||||
|
||||
UNORDERED_AUTO_TEST (merge_set) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> x;
|
||||
boost::unordered_flat_set<int> y;
|
||||
#else
|
||||
boost::unordered_set<int> x;
|
||||
boost::unordered_set<int> y;
|
||||
#endif
|
||||
|
||||
x.merge(y);
|
||||
BOOST_TEST(x.empty());
|
||||
@@ -57,6 +60,7 @@ namespace merge_tests {
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (merge_multiset) {
|
||||
boost::unordered_multiset<int> x;
|
||||
boost::unordered_multiset<int> y;
|
||||
@@ -134,6 +138,7 @@ namespace merge_tests {
|
||||
test::check_equivalent_keys(x);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class X1, class X2>
|
||||
void merge_empty_test(X1*, X2*, test::random_generator generator)
|
||||
@@ -228,6 +233,82 @@ namespace merge_tests {
|
||||
test::check_equivalent_keys(x2);
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<test::movable, test::hash, test::equal_to,
|
||||
std::allocator<test::movable> >* test_set_std_alloc;
|
||||
|
||||
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
|
||||
|
||||
boost::unordered_flat_map<test::movable, test::movable, test::hash, test::equal_to,
|
||||
test::allocator2<test::movable> >* test_map;
|
||||
|
||||
// clang-format off
|
||||
UNORDERED_TEST(merge_empty_test,
|
||||
((test_set_std_alloc))
|
||||
((test_set_std_alloc))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_empty_test,
|
||||
((test_map_std_alloc))
|
||||
((test_map_std_alloc))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_empty_test,
|
||||
((test_set))
|
||||
((test_set))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_empty_test,
|
||||
((test_map))
|
||||
((test_map))
|
||||
((default_generator)(generate_collisions)))
|
||||
|
||||
UNORDERED_TEST(merge_into_empty_test,
|
||||
((test_set_std_alloc))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_into_empty_test,
|
||||
((test_map_std_alloc))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_into_empty_test,
|
||||
((test_set))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_into_empty_test,
|
||||
((test_map))
|
||||
((default_generator)(generate_collisions)))
|
||||
|
||||
UNORDERED_TEST(merge_into_unique_keys_test,
|
||||
((test_set_std_alloc))
|
||||
((test_set_std_alloc))
|
||||
((0)(1)(2))
|
||||
((0)(1)(2))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_into_unique_keys_test,
|
||||
((test_map_std_alloc))
|
||||
((test_map_std_alloc))
|
||||
((0)(1)(2))
|
||||
((0)(1)(2))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_into_unique_keys_test,
|
||||
((test_set))
|
||||
((test_set))
|
||||
((0)(1)(2))
|
||||
((0)(1)(2))
|
||||
((default_generator)(generate_collisions)))
|
||||
UNORDERED_TEST(merge_into_unique_keys_test,
|
||||
((test_map))
|
||||
((test_map))
|
||||
((0)(1)(2))
|
||||
((0)(1)(2))
|
||||
((default_generator)(generate_collisions)))
|
||||
// clang-format on
|
||||
#else
|
||||
boost::unordered_set<test::movable, test::hash, test::equal_to,
|
||||
std::allocator<test::movable> >* test_set_std_alloc;
|
||||
boost::unordered_multiset<test::movable, test::hash, test::equal_to,
|
||||
@@ -248,9 +329,6 @@ namespace merge_tests {
|
||||
boost::unordered_multimap<test::movable, test::movable, test::hash,
|
||||
test::equal_to, test::allocator2<test::movable> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
|
||||
// clang-format off
|
||||
UNORDERED_TEST(merge_empty_test,
|
||||
((test_set_std_alloc)(test_multiset_std_alloc))
|
||||
@@ -332,6 +410,8 @@ UNORDERED_TEST(merge_into_equiv_keys_test,
|
||||
((0)(1)(2))
|
||||
((default_generator)(generate_collisions)))
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2008-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
@@ -18,6 +14,9 @@
|
||||
#include "../helpers/equivalent.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
@@ -68,8 +67,16 @@ namespace move_tests {
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 1.0);
|
||||
#endif
|
||||
test::check_equivalent_keys(y);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
@@ -87,7 +94,7 @@ namespace move_tests {
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_assign_tests1(T*, test::random_generator const& generator)
|
||||
void move_assign_tests1(T* p, test::random_generator const& generator)
|
||||
{
|
||||
{
|
||||
test::check_instances check_;
|
||||
@@ -98,6 +105,19 @@ namespace move_tests {
|
||||
y = create(v, count);
|
||||
#if BOOST_UNORDERED_TEST_MOVING && defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::random_values<T> v;
|
||||
|
||||
T y;
|
||||
y = empty(p);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
@@ -126,7 +146,11 @@ namespace move_tests {
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
|
||||
#endif
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
@@ -142,7 +166,11 @@ namespace move_tests {
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
|
||||
#endif
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
@@ -172,7 +200,11 @@ namespace move_tests {
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
|
||||
#endif
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
}
|
||||
@@ -195,7 +227,11 @@ namespace move_tests {
|
||||
BOOST_TEST(y.empty());
|
||||
test::check_container(y, v2);
|
||||
test::check_equivalent_keys(y);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 2.0);
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
@@ -220,7 +256,11 @@ namespace move_tests {
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 0.5);
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
@@ -233,6 +273,36 @@ namespace move_tests {
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
test::random_values<T> v;
|
||||
T y(0, hf, eq, al1);
|
||||
T x(0, hf, eq, al2);
|
||||
x.max_load_factor(0.25);
|
||||
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
y = boost::move(x);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 0.25);
|
||||
#endif
|
||||
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
? (bool)allocator_type::is_propagate_on_move
|
||||
: (bool)allocator_type::is_propagate_on_assign) {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
} else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -250,7 +320,11 @@ namespace move_tests {
|
||||
}
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 0.25);
|
||||
#endif
|
||||
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
? (bool)allocator_type::is_propagate_on_move
|
||||
@@ -286,7 +360,11 @@ namespace move_tests {
|
||||
|
||||
test::check_container(y, v2);
|
||||
test::check_equivalent_keys(y);
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||
#else
|
||||
BOOST_TEST(y.max_load_factor() == 0.5);
|
||||
#endif
|
||||
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
? (bool)allocator_type::is_propagate_on_move
|
||||
@@ -298,17 +376,65 @@ namespace move_tests {
|
||||
}
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
std::allocator<std::pair<test::object const, test::object> > >*
|
||||
test_map_std_alloc;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::allocator1<std::pair<test::object const, test::object> > >* test_map;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_set_prop_move;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::propagate_move> >* test_map_prop_move;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_set_no_prop_move;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::no_propagate_move> >* test_map_no_prop_move;
|
||||
|
||||
UNORDERED_TEST(move_construct_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(move_assign_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(move_construct_tests2,
|
||||
((test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(move_assign_tests2,
|
||||
((test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
std::allocator<std::pair<test::object const, test::object> > >*
|
||||
test_map_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_map;
|
||||
test::allocator1<std::pair<test::object const, test::object> > >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
||||
test::equal_to,
|
||||
test::allocator2<std::pair<test::object const, test::object> > >*
|
||||
test_multimap;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
@@ -317,11 +443,12 @@ namespace move_tests {
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_multiset_prop_move;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_map_prop_move;
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::propagate_move> >* test_map_prop_move;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_multimap_prop_move;
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::propagate_move> >* test_multimap_prop_move;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
@@ -330,16 +457,12 @@ namespace move_tests {
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_multiset_no_prop_move;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_map_no_prop_move;
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::no_propagate_move> >* test_map_no_prop_move;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_multimap_no_prop_move;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::no_propagate_move> >* test_multimap_no_prop_move;
|
||||
|
||||
UNORDERED_TEST(move_construct_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
|
||||
@@ -367,6 +490,7 @@ namespace move_tests {
|
||||
test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(
|
||||
test_multimap_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
|
||||
// Copyright 2013 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/fwd.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
@@ -201,6 +198,12 @@ namespace noexcept_tests {
|
||||
|
||||
UNORDERED_AUTO_TEST (test_noexcept) {
|
||||
if (have_is_nothrow_move) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_flat_set<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_flat_map<int, int> >::value));
|
||||
#else
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
@@ -209,19 +212,35 @@ namespace noexcept_tests {
|
||||
boost::unordered_map<int, int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multimap<int, int> >::value));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(
|
||||
(!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_flat_set<int, hash_possible_exception> >::value));
|
||||
BOOST_TEST(
|
||||
(!boost::is_nothrow_move_constructible<boost::unordered_flat_set<int,
|
||||
boost::hash<int>, equal_to_possible_exception> >::value));
|
||||
#else
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int, hash_possible_exception> >::value));
|
||||
BOOST_TEST(
|
||||
(!boost::is_nothrow_move_constructible<boost::unordered_multiset<int,
|
||||
boost::hash<int>, equal_to_possible_exception> >::value));
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (test_nothrow_move_when_noexcept) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int, hash_nothrow_move_construct,
|
||||
equal_to_nothrow_move_construct>
|
||||
throwing_set;
|
||||
#else
|
||||
typedef boost::unordered_set<int, hash_nothrow_move_construct,
|
||||
equal_to_nothrow_move_construct>
|
||||
throwing_set;
|
||||
#endif
|
||||
|
||||
if (have_is_nothrow_move) {
|
||||
BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
|
||||
@@ -247,42 +266,76 @@ namespace noexcept_tests {
|
||||
throwing_test_exception = false;
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (test_nothrow_move_assign_when_noexcept) {
|
||||
typedef boost::unordered_set<int, hash_nothrow_move_assign,
|
||||
equal_to_nothrow_move_assign>
|
||||
throwing_set;
|
||||
template <class T>
|
||||
void test_nothrow_move_assign_when_noexcept(T*, test::random_generator const&)
|
||||
{
|
||||
{
|
||||
if (have_is_nothrow_move_assign) {
|
||||
BOOST_TEST(boost::is_nothrow_move_assignable<T>::value);
|
||||
}
|
||||
|
||||
if (have_is_nothrow_move_assign) {
|
||||
BOOST_TEST(boost::is_nothrow_move_assignable<throwing_set>::value);
|
||||
throwing_test_exception = false;
|
||||
|
||||
T x1;
|
||||
T x2;
|
||||
x1.insert(10);
|
||||
x1.insert(50);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
x2.insert(i);
|
||||
}
|
||||
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
x2 = boost::move(x1);
|
||||
BOOST_TEST(x2.size() == 2);
|
||||
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
|
||||
BOOST_TEST(have_is_nothrow_move_assign);
|
||||
} catch (test_exception) {
|
||||
BOOST_TEST(!have_is_nothrow_move_assign);
|
||||
}
|
||||
|
||||
throwing_test_exception = false;
|
||||
}
|
||||
|
||||
throwing_test_exception = false;
|
||||
{
|
||||
if (have_is_nothrow_move_assign) {
|
||||
BOOST_TEST(boost::is_nothrow_move_assignable<T>::value);
|
||||
}
|
||||
|
||||
throwing_set x1;
|
||||
throwing_set x2;
|
||||
x1.insert(10);
|
||||
x1.insert(50);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
x2.insert(i);
|
||||
throwing_test_exception = false;
|
||||
|
||||
T x1;
|
||||
T x2;
|
||||
x1.insert(10);
|
||||
x1.insert(50);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
x2.insert(i);
|
||||
}
|
||||
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
x1 = boost::move(x2);
|
||||
BOOST_TEST(x1.size() == 100);
|
||||
BOOST_TEST(have_is_nothrow_move_assign);
|
||||
} catch (test_exception) {
|
||||
BOOST_TEST(!have_is_nothrow_move_assign);
|
||||
}
|
||||
|
||||
throwing_test_exception = false;
|
||||
}
|
||||
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
x2 = boost::move(x1);
|
||||
BOOST_TEST(x2.size() == 2);
|
||||
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
|
||||
BOOST_TEST(have_is_nothrow_move_assign);
|
||||
} catch (test_exception) {
|
||||
BOOST_TEST(!have_is_nothrow_move_assign);
|
||||
}
|
||||
|
||||
throwing_test_exception = false;
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (test_nothrow_swap_when_noexcept) {
|
||||
#if BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int, hash_nothrow_swap,
|
||||
equal_to_nothrow_swap>
|
||||
throwing_set;
|
||||
#else
|
||||
typedef boost::unordered_set<int, hash_nothrow_swap, equal_to_nothrow_swap>
|
||||
throwing_set;
|
||||
#endif
|
||||
|
||||
if (have_is_nothrow_swap) {
|
||||
BOOST_TEST(boost::is_nothrow_swappable<throwing_set>::value);
|
||||
@@ -318,4 +371,93 @@ namespace noexcept_tests {
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class T> class allocator1
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(allocator1)
|
||||
allocator1 operator=(BOOST_COPY_ASSIGN_REF(allocator1));
|
||||
allocator1 operator=(BOOST_RV_REF(allocator1));
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
allocator1() {}
|
||||
allocator1(allocator1 const&) {}
|
||||
|
||||
template <class U> allocator1(allocator1<U> const&) {}
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
noexcept_tests::test_throw("Allocate");
|
||||
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t) { ::operator delete(p); }
|
||||
|
||||
friend bool operator==(allocator1 const&, allocator1 const&) { return true; }
|
||||
friend bool operator!=(allocator1 const&, allocator1 const&) { return false; }
|
||||
};
|
||||
|
||||
template <class T> class allocator2
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(allocator2)
|
||||
allocator2 operator=(BOOST_COPY_ASSIGN_REF(allocator2));
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef boost::true_type propagate_on_container_move_assignment;
|
||||
|
||||
allocator2() {}
|
||||
allocator2(allocator2 const&) {}
|
||||
|
||||
template <class U> allocator2(allocator2<U> const&) {}
|
||||
|
||||
allocator2& operator=(BOOST_RV_REF(allocator2)) { return *this; }
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
noexcept_tests::test_throw("Allocate");
|
||||
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t) { ::operator delete(p); }
|
||||
|
||||
friend bool operator==(allocator2 const&, allocator2 const&) { return true; }
|
||||
friend bool operator!=(allocator2 const&, allocator2 const&) { return false; }
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST (prelim_allocator_checks) {
|
||||
BOOST_TEST(boost::allocator_is_always_equal<allocator1<int> >::type::value);
|
||||
BOOST_TEST(!boost::allocator_propagate_on_container_move_assignment<
|
||||
allocator1<int> >::type::value);
|
||||
|
||||
BOOST_TEST(boost::allocator_is_always_equal<allocator2<int> >::type::value);
|
||||
BOOST_TEST(boost::allocator_propagate_on_container_move_assignment<
|
||||
allocator2<int> >::type::value);
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int, noexcept_tests::hash_nothrow_move_assign,
|
||||
noexcept_tests::equal_to_nothrow_move_assign, allocator1<int> >*
|
||||
throwing_set_alloc1;
|
||||
|
||||
boost::unordered_flat_set<int, noexcept_tests::hash_nothrow_move_assign,
|
||||
noexcept_tests::equal_to_nothrow_move_assign, allocator2<int> >*
|
||||
throwing_set_alloc2;
|
||||
|
||||
UNORDERED_TEST(test_nothrow_move_assign_when_noexcept,
|
||||
((throwing_set_alloc1)(throwing_set_alloc2))((default_generator)))
|
||||
#else
|
||||
boost::unordered_set<int, noexcept_tests::hash_nothrow_move_assign,
|
||||
noexcept_tests::equal_to_nothrow_move_assign, allocator1<int> >*
|
||||
throwing_set_alloc1;
|
||||
|
||||
boost::unordered_set<int, noexcept_tests::hash_nothrow_move_assign,
|
||||
noexcept_tests::equal_to_nothrow_move_assign, allocator2<int> >*
|
||||
throwing_set_alloc2;
|
||||
|
||||
UNORDERED_TEST(test_nothrow_move_assign_when_noexcept,
|
||||
((throwing_set_alloc1)(throwing_set_alloc2))((default_generator)))
|
||||
#endif
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
666
test/unordered/post_move_tests.cpp
Normal file
666
test/unordered/post_move_tests.cpp
Normal file
@@ -0,0 +1,666 @@
|
||||
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "../helpers/unordered.hpp"
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
#include "../objects/cxx11_allocator.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
#include "../helpers/equivalent.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace move_tests {
|
||||
test::seed_t initialize_seed(98624);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#define BOOST_UNORDERED_TEST_MOVING 1
|
||||
#else
|
||||
#define BOOST_UNORDERED_TEST_MOVING 0
|
||||
#endif
|
||||
|
||||
template <class T> T empty(T*) { return T(); }
|
||||
|
||||
template <class T>
|
||||
T create(test::random_values<T> const& v, test::object_count& count)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T create(test::random_values<T> const& v, test::object_count& count,
|
||||
typename T::hasher hf, typename T::key_equal eq,
|
||||
typename T::allocator_type al, float mlf)
|
||||
{
|
||||
T x(0, hf, eq, al);
|
||||
x.max_load_factor(mlf);
|
||||
x.insert(v.begin(), v.end());
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T> T const& get_key(T const& t) { return t; }
|
||||
|
||||
template <class K, class V> K const& get_key(std::pair<K const, V> const& kv)
|
||||
{
|
||||
return kv.first;
|
||||
}
|
||||
|
||||
template <class T> T const& get_value(T const& t) { return t; }
|
||||
|
||||
template <class K, class V> K const& get_value(std::pair<K const, V> const& kv)
|
||||
{
|
||||
return kv.second;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_range(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(v.begin(), v.end());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_single(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(*v.begin());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_single_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(y.end(), *v.begin());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> struct insert_or_assign_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct insert_or_assign_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
|
||||
y.insert_or_assign(get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void insert_or_assign(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
insert_or_assign_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct insert_or_assign_hint_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct insert_or_assign_hint_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.insert_or_assign(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void insert_or_assign_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
insert_or_assign_hint_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct try_emplace_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct try_emplace_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.try_emplace(get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void try_emplace(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
try_emplace_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct try_emplace_hint_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct try_emplace_hint_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.try_emplace(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void try_emplace_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
try_emplace_hint_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct at_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct at_invoker<boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
BOOST_TRY { y.at(get_key(*v.begin())); }
|
||||
BOOST_CATCH(...) {}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> static void at(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
at_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct index_operator_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct index_operator_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y[get_key(*v.begin())] = get_value(*v.begin());
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void index_operator(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
index_operator_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> static void clear(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.clear();
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void capacity(T& y, test::random_values<T> const&)
|
||||
{
|
||||
(void)y.empty();
|
||||
(void)y.size();
|
||||
(void)y.max_size();
|
||||
(void)y.load_factor();
|
||||
(void)y.max_load_factor();
|
||||
(void)y.hash_function();
|
||||
(void)y.key_eq();
|
||||
(void)y.get_allocator();
|
||||
}
|
||||
|
||||
template <class T> static void iterators(T& y, test::random_values<T> const&)
|
||||
{
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void erase_range(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.erase(y.begin(), y.end());
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void erase_key(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.erase(get_key(*v.begin()));
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void lookup(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.count(get_key(*v.begin()));
|
||||
(void)y.find(get_key(*v.begin()));
|
||||
(void)y.contains(get_key(*v.begin()));
|
||||
(void)y.equal_range(get_key(*v.begin()));
|
||||
}
|
||||
|
||||
template <class T> static void reserve(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.reserve(1337);
|
||||
BOOST_TEST_GT(y.bucket_count(), 1337u);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void copy_assignment(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
y = x;
|
||||
BOOST_TEST_EQ(y.size(), x.size());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void move_assignment(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
std::size_t const size = x.size();
|
||||
y = boost::move(x);
|
||||
BOOST_TEST_GE(y.size(), size);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void equal(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
(void)(y == x);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void extract(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.extract(get_key(*v.begin()));
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void merge(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
if (y.get_allocator() == x.get_allocator()) {
|
||||
y.merge(x);
|
||||
}
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class X> bool pred(X const&) { return true; }
|
||||
|
||||
template <class T>
|
||||
static void erase_with_pred(T& y, test::random_values<T> const&)
|
||||
{
|
||||
erase_if(y, pred<typename T::value_type>);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void container_swap(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
if (boost::allocator_propagate_on_container_swap<
|
||||
typename T::allocator_type>::type::value ||
|
||||
x.get_allocator() == y.get_allocator()) {
|
||||
y.swap(x);
|
||||
}
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void buckets(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.begin(0);
|
||||
(void)y.end(0);
|
||||
(void)y.bucket_count();
|
||||
(void)y.max_bucket_count();
|
||||
(void)y.bucket_size(0);
|
||||
(void)y.bucket(get_key(*v.begin()));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void double_move_construct(T& y, test::random_values<T> const&)
|
||||
{
|
||||
T x = boost::move(y);
|
||||
x.clear();
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
BOOST_TEST_EQ(x.size(),
|
||||
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void double_move_assign(T& y, test::random_values<T> const&)
|
||||
{
|
||||
T x;
|
||||
x = boost::move(y);
|
||||
x.clear();
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
BOOST_TEST_EQ(x.size(),
|
||||
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void post_move_tests(T* ptr, test::random_generator const& generator)
|
||||
{
|
||||
// clang-format off
|
||||
void (*fps[])(T&, test::random_values<T> const&) = {
|
||||
insert_range<T>,
|
||||
insert_single<T>,
|
||||
insert_single_hint<T>,
|
||||
insert_or_assign<T>,
|
||||
insert_or_assign_hint<T>,
|
||||
try_emplace<T>,
|
||||
try_emplace_hint<T>,
|
||||
at<T>,
|
||||
index_operator<T>,
|
||||
clear<T>,
|
||||
capacity<T>,
|
||||
iterators<T>,
|
||||
erase_range<T>,
|
||||
erase_key<T>,
|
||||
lookup<T>,
|
||||
reserve<T>,
|
||||
copy_assignment<T>,
|
||||
move_assignment<T>,
|
||||
equal<T>,
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
extract<T>,
|
||||
buckets<T>,
|
||||
#endif
|
||||
merge<T>,
|
||||
erase_with_pred<T>,
|
||||
container_swap<T>,
|
||||
double_move_construct<T>,
|
||||
double_move_assign<T>
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
std::size_t const len = (sizeof(fps) / sizeof(*(fps)));
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> const v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(boost::move(y));
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
typename T::hasher hf(1);
|
||||
typename T::key_equal eq(1);
|
||||
typename T::allocator_type al1(1);
|
||||
typename T::allocator_type al2(2);
|
||||
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||
T x(boost::move(y), al2);
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
#else
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(empty(ptr));
|
||||
x = boost::move(y);
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
typename T::hasher hf(1);
|
||||
typename T::key_equal eq(1);
|
||||
typename T::allocator_type al1(1);
|
||||
typename T::allocator_type al2(2);
|
||||
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(al2);
|
||||
x = boost::move(y);
|
||||
|
||||
bool b = boost::allocator_propagate_on_container_move_assignment<
|
||||
typename T::allocator_type>::type::value;
|
||||
if (b) {
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#else
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
|
||||
#endif
|
||||
} else {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
#else
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
#endif
|
||||
}
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
std::allocator<std::pair<test::object const, test::object> > >*
|
||||
test_map_std_alloc;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::allocator1<std::pair<test::object const, test::object> > >* test_map;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_set_prop_move;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::propagate_move> >* test_map_prop_move;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_set_no_prop_move;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::no_propagate_move> >* test_map_no_prop_move;
|
||||
|
||||
UNORDERED_TEST(post_move_tests,
|
||||
((test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<std::pair<test::object const, test::object> > >*
|
||||
test_map_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<std::pair<test::object const, test::object> > >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::allocator2<std::pair<test::object const, test::object> > >*
|
||||
test_multimap;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_set_prop_move;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_multiset_prop_move;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::propagate_move> >* test_map_prop_move;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::propagate_move> >* test_multimap_prop_move;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_set_no_prop_move;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_multiset_no_prop_move;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::no_propagate_move> >* test_map_no_prop_move;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::no_propagate_move> >* test_multimap_no_prop_move;
|
||||
|
||||
UNORDERED_TEST(post_move_tests,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_move)(
|
||||
test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)(
|
||||
test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(
|
||||
test_multimap_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
@@ -81,6 +77,305 @@ namespace rehash_tests {
|
||||
BOOST_TEST(postcondition(x, 0));
|
||||
}
|
||||
|
||||
template <class X> void rehash_empty_tracking(X*, test::random_generator)
|
||||
{
|
||||
// valid for all load factors
|
||||
float const max_load_factors[] = {
|
||||
0.5f, 1.0f, 1e6f, std::numeric_limits<float>::infinity()};
|
||||
|
||||
std::size_t const max_load_factors_len =
|
||||
sizeof(max_load_factors) / sizeof(*max_load_factors);
|
||||
|
||||
for (std::size_t i = 0; i < max_load_factors_len; ++i) {
|
||||
X x;
|
||||
BOOST_TEST_EQ(x.size(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
x.max_load_factor(max_load_factors[i]);
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
|
||||
x.rehash(0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
|
||||
x.rehash(1000);
|
||||
BOOST_TEST_GE(x.bucket_count(), 1000u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
x.rehash(0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
|
||||
x.rehash(1000);
|
||||
BOOST_TEST_GE(x.bucket_count(), 1000u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
x.rehash(10);
|
||||
BOOST_TEST_GE(x.bucket_count(), 10u);
|
||||
BOOST_TEST_LT(x.bucket_count(), 1000u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
BOOST_TEST_LT(x.bucket_count(), 1000u);
|
||||
|
||||
x.rehash(1000);
|
||||
BOOST_TEST_GE(x.bucket_count(), 1000u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
x.rehash(0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < max_load_factors_len; ++i) {
|
||||
typedef typename X::size_type size_type;
|
||||
|
||||
X x;
|
||||
BOOST_TEST_EQ(x.size(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
float const mlf = boost::unordered::detail::foa::mlf;
|
||||
x.max_load_factor(max_load_factors[i]);
|
||||
#else
|
||||
float const mlf = max_load_factors[i];
|
||||
x.max_load_factor(mlf);
|
||||
#endif
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
|
||||
x.reserve(0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
|
||||
x.reserve(1000);
|
||||
BOOST_TEST_GE(
|
||||
x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
x.reserve(0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
|
||||
x.reserve(1000);
|
||||
BOOST_TEST_GE(
|
||||
x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
x.reserve(10);
|
||||
BOOST_TEST_GE(
|
||||
x.bucket_count(), static_cast<size_type>(std::ceil(10 / mlf)));
|
||||
BOOST_TEST_LT(x.bucket_count(), 1000u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
BOOST_TEST_LT(x.bucket_count(), 1000u);
|
||||
|
||||
x.reserve(1000);
|
||||
BOOST_TEST_GE(
|
||||
x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
x.reserve(0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void rehash_nonempty_tracking(X*, test::random_generator generator)
|
||||
{
|
||||
test::random_values<X> const v(1000, generator);
|
||||
|
||||
typedef typename X::size_type size_type;
|
||||
|
||||
float const max_load_factors[] = {0.5f, 1.0f, 1e2f};
|
||||
|
||||
size_type const max_load_factors_len =
|
||||
sizeof(max_load_factors) / sizeof(*max_load_factors);
|
||||
|
||||
for (size_type i = 0; i < max_load_factors_len; ++i) {
|
||||
float const mlf = max_load_factors[i];
|
||||
|
||||
X x(v.begin(), v.end());
|
||||
BOOST_TEST_GT(x.size(), 0u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
x.max_load_factor(mlf);
|
||||
|
||||
size_type bucket_count = x.bucket_count();
|
||||
|
||||
{
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
|
||||
x.rehash(0);
|
||||
BOOST_TEST_GE(x.bucket_count(),
|
||||
static_cast<size_type>(
|
||||
std::floor(static_cast<float>(x.size()) / x.max_load_factor())));
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
bucket_count = x.bucket_count();
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_GT(bucket_count, 0u);
|
||||
|
||||
x.rehash(2 * x.bucket_count());
|
||||
BOOST_TEST_GT(x.bucket_count(), bucket_count);
|
||||
|
||||
bucket_count = x.bucket_count();
|
||||
}
|
||||
|
||||
{
|
||||
float const old_mlf = x.max_load_factor();
|
||||
|
||||
BOOST_TEST_GT(bucket_count, 0u);
|
||||
|
||||
x.rehash(bucket_count / 4);
|
||||
BOOST_TEST_LT(x.bucket_count(), bucket_count);
|
||||
|
||||
x.max_load_factor(std::numeric_limits<float>::infinity());
|
||||
x.rehash(0);
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
|
||||
x.max_load_factor(old_mlf);
|
||||
}
|
||||
|
||||
{
|
||||
std::size_t const max_load =
|
||||
static_cast<std::size_t>(static_cast<double>(x.max_load_factor()) *
|
||||
static_cast<double>(x.bucket_count()));
|
||||
|
||||
while (x.size() < max_load) {
|
||||
test::random_values<X> const t(max_load, generator);
|
||||
typename test::random_values<X>::const_iterator pos = t.begin();
|
||||
typename test::random_values<X>::const_iterator end = t.end();
|
||||
for (; pos != end; ++pos) {
|
||||
x.insert(*pos);
|
||||
if (x.size() == max_load) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (x.size() > max_load) {
|
||||
x.erase(x.begin());
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(x.size(), max_load);
|
||||
|
||||
bucket_count = x.bucket_count();
|
||||
x.rehash(x.bucket_count());
|
||||
BOOST_TEST_EQ(x.bucket_count(), bucket_count);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_type i = 0; i < max_load_factors_len; ++i) {
|
||||
X x(v.begin(), v.end());
|
||||
BOOST_TEST_GT(x.size(), 0u);
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
float const mlf = max_load_factors[i];
|
||||
x.max_load_factor(mlf);
|
||||
|
||||
size_type bucket_count = x.bucket_count();
|
||||
|
||||
{
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
|
||||
x.reserve(0);
|
||||
BOOST_TEST_GE(x.bucket_count(),
|
||||
static_cast<size_type>(
|
||||
std::floor(static_cast<float>(x.size()) / x.max_load_factor())));
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
|
||||
bucket_count = x.bucket_count();
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
|
||||
x.reserve(
|
||||
2 * (static_cast<size_type>(
|
||||
std::floor(static_cast<float>(x.size()) / x.max_load_factor()) +
|
||||
std::floor(static_cast<float>(x.size()) * x.max_load_factor()))));
|
||||
|
||||
BOOST_TEST_GT(x.bucket_count(), bucket_count);
|
||||
|
||||
bucket_count = x.bucket_count();
|
||||
BOOST_TEST_GT(bucket_count, 1u);
|
||||
}
|
||||
|
||||
{
|
||||
float const old_mlf = x.max_load_factor();
|
||||
|
||||
BOOST_TEST_GT(bucket_count, 4u);
|
||||
|
||||
x.reserve(bucket_count / 4);
|
||||
BOOST_TEST_LT(x.bucket_count(), bucket_count);
|
||||
|
||||
x.max_load_factor(std::numeric_limits<float>::infinity());
|
||||
x.reserve(0);
|
||||
BOOST_TEST_GT(x.bucket_count(), 0u);
|
||||
|
||||
x.max_load_factor(old_mlf);
|
||||
}
|
||||
|
||||
{
|
||||
std::size_t const max_load =
|
||||
static_cast<std::size_t>(static_cast<double>(x.max_load_factor()) *
|
||||
static_cast<double>(x.bucket_count()));
|
||||
|
||||
while (x.size() < max_load) {
|
||||
test::random_values<X> const t(max_load, generator);
|
||||
typename test::random_values<X>::const_iterator pos = t.begin();
|
||||
typename test::random_values<X>::const_iterator end = t.end();
|
||||
for (; pos != end; ++pos) {
|
||||
x.insert(*pos);
|
||||
if (x.size() == max_load) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (x.size() > max_load) {
|
||||
x.erase(x.begin());
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(x.size(), max_load);
|
||||
|
||||
bucket_count = x.bucket_count();
|
||||
x.reserve(x.size());
|
||||
BOOST_TEST_EQ(x.bucket_count(), bucket_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class X> void rehash_test1(X*, test::random_generator generator)
|
||||
{
|
||||
test::random_values<X> v(1000, generator);
|
||||
@@ -125,6 +420,15 @@ namespace rehash_tests {
|
||||
X x;
|
||||
x.max_load_factor(0.25);
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
x.reserve(10000);
|
||||
BOOST_TEST(x.bucket_count() >= 10000);
|
||||
|
||||
x.reserve(0);
|
||||
|
||||
x.reserve(10000000);
|
||||
BOOST_TEST(x.bucket_count() >= 10000000);
|
||||
#else
|
||||
x.reserve(10000);
|
||||
BOOST_TEST(x.bucket_count() >= 40000);
|
||||
|
||||
@@ -132,6 +436,7 @@ namespace rehash_tests {
|
||||
|
||||
x.reserve(10000000);
|
||||
BOOST_TEST(x.bucket_count() >= 40000000);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X> void reserve_test1(X*, test::random_generator generator)
|
||||
@@ -192,6 +497,47 @@ namespace rehash_tests {
|
||||
}
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int>* int_set_ptr;
|
||||
boost::unordered_flat_map<test::movable, test::movable, test::hash,
|
||||
test::equal_to, test::allocator2<test::movable> >* test_map_ptr;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set_tracking;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::allocator1<std::pair<test::object const, test::object> > >*
|
||||
test_map_tracking;
|
||||
|
||||
UNORDERED_TEST(rehash_empty_test1, ((int_set_ptr)(test_map_ptr)))
|
||||
UNORDERED_TEST(rehash_empty_test2,
|
||||
((int_set_ptr)(test_map_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(rehash_empty_test3,
|
||||
((int_set_ptr)(test_map_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(
|
||||
rehash_test1, ((int_set_ptr)(test_map_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(reserve_empty_test1, ((int_set_ptr)(test_map_ptr)))
|
||||
UNORDERED_TEST(reserve_empty_test2, ((int_set_ptr)(test_map_ptr)))
|
||||
UNORDERED_TEST(
|
||||
reserve_test1, ((int_set_ptr)(test_map_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(
|
||||
reserve_test2, ((int_set_ptr)(test_map_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(rehash_empty_tracking,
|
||||
((test_set_tracking)(test_map_tracking))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(rehash_nonempty_tracking,
|
||||
((test_set_tracking)(test_map_tracking))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_set<int>* int_set_ptr;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multiset_ptr;
|
||||
@@ -199,9 +545,17 @@ namespace rehash_tests {
|
||||
test::allocator2<test::movable> >* test_map_ptr;
|
||||
boost::unordered_multimap<int, int>* int_multimap_ptr;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set_tracking;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multiset_tracking;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<std::pair<test::object const, test::object> > >*
|
||||
test_map_tracking;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::allocator1<std::pair<test::object const, test::object> > >*
|
||||
test_multimap_tracking;
|
||||
|
||||
UNORDERED_TEST(rehash_empty_test1,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
|
||||
@@ -224,6 +578,13 @@ namespace rehash_tests {
|
||||
UNORDERED_TEST(reserve_test2,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(rehash_empty_tracking,
|
||||
((test_set_tracking)(test_multiset_tracking)(test_map_tracking)(test_multimap_tracking))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(rehash_nonempty_tracking,
|
||||
((test_set_tracking)(test_multiset_tracking)(test_map_tracking)(test_multimap_tracking))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
@@ -113,8 +108,8 @@ template <class UnorderedContainer> void reserve_tests()
|
||||
s.max_load_factor(0.37f);
|
||||
s.reserve(count);
|
||||
|
||||
std::size_t expected_bucket_count =
|
||||
static_cast<std::size_t>(std::ceil(static_cast<float>(count) / 0.37f));
|
||||
std::size_t expected_bucket_count = static_cast<std::size_t>(
|
||||
std::ceil(static_cast<float>(count) / s.max_load_factor()));
|
||||
|
||||
BOOST_TEST_GE(total_allocation, expected_bucket_count * sizeof(void*));
|
||||
BOOST_TEST_GE(s.bucket_count(), expected_bucket_count);
|
||||
@@ -173,6 +168,12 @@ template <class UnorderedContainer> void rehash_tests()
|
||||
// note, the test is vulnerable to cases where the next calculated bucket
|
||||
// count can exceed `prev_count + count`
|
||||
//
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST_LT(s.bucket_count(), prev_count + count);
|
||||
BOOST_TEST_LE(total_allocation,
|
||||
(prev_count + count) * sizeof(typename UnorderedContainer::value_type) +
|
||||
((prev_count + count) / 15 + 1) * 16);
|
||||
#else
|
||||
std::size_t const estimated_bucket_group_size =
|
||||
3 * sizeof(void*) + sizeof(std::size_t);
|
||||
std::size_t const estimated_bucket_groups =
|
||||
@@ -182,6 +183,7 @@ template <class UnorderedContainer> void rehash_tests()
|
||||
BOOST_TEST_LE(total_allocation,
|
||||
(prev_count + count) * sizeof(void*) +
|
||||
estimated_bucket_group_size * estimated_bucket_groups);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_TEST_GT(num_allocations, 0u);
|
||||
@@ -214,6 +216,28 @@ UNORDERED_AUTO_TEST (unordered_set_reserve) {
|
||||
BOOST_ASSERT(A<int>(b) == a);
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int*, boost::hash<int*>,
|
||||
std::equal_to<int*>, A<int*> >
|
||||
unordered_set;
|
||||
|
||||
typedef boost::unordered_flat_map<int*, int*, boost::hash<int*>,
|
||||
std::equal_to<int*>, A<std::pair<int const*, int*> > >
|
||||
unordered_map;
|
||||
|
||||
bucket_count_constructor<unordered_set>();
|
||||
bucket_count_constructor<unordered_map>();
|
||||
|
||||
range_bucket_constructor<unordered_set>();
|
||||
range_bucket_constructor<unordered_map>();
|
||||
|
||||
reserve_tests<unordered_set>();
|
||||
reserve_tests<unordered_map>();
|
||||
|
||||
rehash_tests<unordered_set>();
|
||||
rehash_tests<unordered_map>();
|
||||
|
||||
#else
|
||||
typedef boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
A<int> >
|
||||
unordered_set;
|
||||
@@ -249,6 +273,7 @@ UNORDERED_AUTO_TEST (unordered_set_reserve) {
|
||||
rehash_tests<unordered_map>();
|
||||
rehash_tests<unordered_multiset>();
|
||||
rehash_tests<unordered_multimap>();
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -2,14 +2,8 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/unordered.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
|
||||
#include <memory>
|
||||
@@ -107,8 +101,7 @@ public:
|
||||
// ever using it with an int with has a trivial destructor so it eliminates
|
||||
// the code and generates a warning about an unused variable
|
||||
//
|
||||
template <class U>
|
||||
void destroy(U* p)
|
||||
template <class U> void destroy(U* p)
|
||||
{
|
||||
(void)p;
|
||||
p->~U();
|
||||
@@ -192,8 +185,7 @@ public:
|
||||
// ever using it with an int with has a trivial destructor so it eliminates
|
||||
// the code and generates a warning about an unused variable
|
||||
//
|
||||
template <class U>
|
||||
void destroy(U* p)
|
||||
template <class U> void destroy(U* p)
|
||||
{
|
||||
(void)p;
|
||||
p->~U();
|
||||
@@ -224,13 +216,15 @@ template <class C1, class C2> void scary_test()
|
||||
typename C2::const_iterator cbegin(x.cbegin());
|
||||
BOOST_TEST(cbegin == x.cend());
|
||||
|
||||
BOOST_ASSERT(x.bucket_count() > 0);
|
||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typename C2::local_iterator lbegin(x.begin(0));
|
||||
BOOST_TEST(lbegin == x.end(0));
|
||||
|
||||
typename C2::const_local_iterator clbegin(x.cbegin(0));
|
||||
BOOST_TEST(clbegin == x.cend(0));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <
|
||||
@@ -316,11 +310,16 @@ void set_scary_test()
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (scary_tests) {
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
map_scary_test<boost::unordered_flat_map>();
|
||||
set_scary_test<boost::unordered_flat_set>();
|
||||
#else
|
||||
map_scary_test<boost::unordered_map>();
|
||||
map_scary_test<boost::unordered_multimap>();
|
||||
|
||||
set_scary_test<boost::unordered_set>();
|
||||
set_scary_test<boost::unordered_multiset>();
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -19,12 +19,7 @@ int main() {}
|
||||
// https://github.com/boostorg/unordered/issues/22
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
@@ -32,10 +27,10 @@ int main() {}
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
#include <scoped_allocator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <scoped_allocator>
|
||||
|
||||
namespace test {
|
||||
template <class T> struct allocator
|
||||
@@ -70,9 +65,15 @@ typedef std::scoped_allocator_adaptor<test::allocator<pair_type>,
|
||||
test::allocator<boost::uint64_t> >
|
||||
allocator_type;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_map<const boost::uint64_t, vector_type,
|
||||
boost::hash<boost::uint64_t>, std::equal_to<boost::uint64_t>, allocator_type>
|
||||
map_type;
|
||||
#else
|
||||
typedef boost::unordered_map<const boost::uint64_t, vector_type,
|
||||
boost::hash<boost::uint64_t>, std::equal_to<boost::uint64_t>, allocator_type>
|
||||
map_type;
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (scoped_allocator) {
|
||||
allocator_type alloc(
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// This test checks the runtime requirements of containers.
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include <cstdlib>
|
||||
@@ -93,7 +89,11 @@ UNORDERED_AUTO_TEST (simple_tests) {
|
||||
srand(14878);
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_set<int> set;
|
||||
#else
|
||||
boost::unordered_set<int> set;
|
||||
#endif
|
||||
simple_test(set);
|
||||
|
||||
set.insert(1);
|
||||
@@ -101,6 +101,7 @@ UNORDERED_AUTO_TEST (simple_tests) {
|
||||
set.insert(1456);
|
||||
simple_test(set);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||
boost::unordered_multiset<int> multiset;
|
||||
simple_test(multiset);
|
||||
@@ -111,15 +112,21 @@ UNORDERED_AUTO_TEST (simple_tests) {
|
||||
multiset.insert(index);
|
||||
}
|
||||
simple_test(multiset);
|
||||
#endif
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<int, int> map;
|
||||
#else
|
||||
boost::unordered_map<int, int> map;
|
||||
#endif
|
||||
|
||||
for (int i2 = 0; i2 < 1000; ++i2) {
|
||||
map.insert(std::pair<const int, int>(rand(), rand()));
|
||||
}
|
||||
simple_test(map);
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
||||
boost::unordered_multimap<int, int> multimap;
|
||||
|
||||
@@ -129,6 +136,7 @@ UNORDERED_AUTO_TEST (simple_tests) {
|
||||
multimap.insert(std::pair<const int, int>(index, rand()));
|
||||
}
|
||||
simple_test(multimap);
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Copyright 2022 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <algorithm>
|
||||
@@ -139,6 +135,53 @@ namespace swap_tests {
|
||||
}
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
template <typename T> bool is_propagate(T*)
|
||||
{
|
||||
return T::allocator_type::is_propagate_on_swap;
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_map;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
test_set_prop_swap;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
test_map_prop_swap;
|
||||
|
||||
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
test_set_no_prop_swap;
|
||||
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
test_map_no_prop_swap;
|
||||
|
||||
UNORDERED_AUTO_TEST (check_traits) {
|
||||
BOOST_TEST(!is_propagate(test_set));
|
||||
BOOST_TEST(is_propagate(test_set_prop_swap));
|
||||
BOOST_TEST(!is_propagate(test_set_no_prop_swap));
|
||||
}
|
||||
|
||||
UNORDERED_TEST(swap_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_map)(test_set_prop_swap)(test_map_prop_swap)(test_set_no_prop_swap)(test_map_no_prop_swap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(swap_tests2,
|
||||
((test_set)(test_map)(test_set_prop_swap)(test_map_prop_swap)(test_set_no_prop_swap)(test_map_no_prop_swap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#else
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
@@ -178,15 +221,6 @@ namespace swap_tests {
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
test_multimap_no_prop_swap;
|
||||
|
||||
template <typename T> bool is_propagate(T*)
|
||||
{
|
||||
return T::allocator_type::is_propagate_on_swap;
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_AUTO_TEST (check_traits) {
|
||||
BOOST_TEST(!is_propagate(test_set));
|
||||
BOOST_TEST(is_propagate(test_set_prop_swap));
|
||||
@@ -207,5 +241,6 @@ namespace swap_tests {
|
||||
test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)(
|
||||
test_multimap_no_prop_swap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
#endif
|
||||
}
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
@@ -1053,14 +1048,25 @@ template <class UnorderedMap> struct convertible_to_const_iterator
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_map<int, int, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
transparent_unordered_map;
|
||||
#else
|
||||
typedef boost::unordered_map<int, int, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
transparent_unordered_map;
|
||||
#endif
|
||||
|
||||
// test that in the presence of the member function template `erase()`, we still
|
||||
// invoke the correct iterator overloads when the type is implicitly convertible
|
||||
//
|
||||
transparent_unordered_map::iterator map_erase_overload_compile_test()
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
void
|
||||
#else
|
||||
transparent_unordered_map::iterator
|
||||
#endif
|
||||
map_erase_overload_compile_test()
|
||||
{
|
||||
convertible_to_iterator<transparent_unordered_map> c;
|
||||
transparent_unordered_map map;
|
||||
@@ -1069,7 +1075,11 @@ transparent_unordered_map::iterator map_erase_overload_compile_test()
|
||||
return map.erase(c);
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
void
|
||||
#else
|
||||
transparent_unordered_map::const_iterator
|
||||
#endif
|
||||
map_erase_const_overload_compile_test()
|
||||
{
|
||||
convertible_to_const_iterator<transparent_unordered_map> c;
|
||||
@@ -1079,6 +1089,7 @@ map_erase_const_overload_compile_test()
|
||||
return map.erase(c);
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_multimap<int, int, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
transparent_unordered_multimap;
|
||||
@@ -1101,6 +1112,7 @@ multimap_erase_const_overload_compile_test()
|
||||
pos = c;
|
||||
return map.erase(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class UnorderedMap> void test_map_transparent_erase()
|
||||
{
|
||||
@@ -1197,14 +1209,25 @@ template <class UnorderedMap> void test_map_non_transparent_erase()
|
||||
BOOST_TEST_EQ(key::count_, key_count);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<int, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
transparent_unordered_set;
|
||||
#else
|
||||
typedef boost::unordered_set<int, transparent_hasher, transparent_key_equal>
|
||||
transparent_unordered_set;
|
||||
|
||||
typedef boost::unordered_multiset<int, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
transparent_unordered_multiset;
|
||||
#endif
|
||||
|
||||
transparent_unordered_set::iterator set_erase_overload_compile_test()
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
void
|
||||
#else
|
||||
transparent_unordered_set::iterator
|
||||
#endif
|
||||
set_erase_overload_compile_test()
|
||||
{
|
||||
convertible_to_iterator<transparent_unordered_set> c;
|
||||
transparent_unordered_set set;
|
||||
@@ -1213,7 +1236,11 @@ transparent_unordered_set::iterator set_erase_overload_compile_test()
|
||||
return set.erase(c);
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
void
|
||||
#else
|
||||
transparent_unordered_set::const_iterator
|
||||
#endif
|
||||
set_erase_const_overload_compile_test()
|
||||
{
|
||||
convertible_to_const_iterator<transparent_unordered_set> c;
|
||||
@@ -1223,6 +1250,7 @@ set_erase_const_overload_compile_test()
|
||||
return set.erase(c);
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
transparent_unordered_multiset::iterator multiset_erase_overload_compile_test()
|
||||
{
|
||||
convertible_to_iterator<transparent_unordered_multiset> c;
|
||||
@@ -1241,6 +1269,7 @@ multiset_erase_const_overload_compile_test()
|
||||
pos = c;
|
||||
return set.erase(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class UnorderedSet> void test_set_transparent_erase()
|
||||
{
|
||||
@@ -1337,6 +1366,7 @@ template <class UnorderedSet> void test_set_non_transparent_erase()
|
||||
BOOST_TEST_EQ(key::count_, key_count);
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
// test that in the presence of the member function template `extract()`, we
|
||||
// still invoke the correct iterator overloads when the type is implicitly
|
||||
// convertible
|
||||
@@ -1359,9 +1389,11 @@ multimap_extract_const_overload_compile_test()
|
||||
pos = c;
|
||||
return map.extract(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class UnorderedMap> void test_map_transparent_extract()
|
||||
{
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename UnorderedMap::node_type node_type;
|
||||
typedef typename UnorderedMap::const_iterator const_iterator;
|
||||
typedef std::pair<const_iterator, const_iterator> const_iterator_pair;
|
||||
@@ -1397,10 +1429,12 @@ template <class UnorderedMap> void test_map_transparent_extract()
|
||||
BOOST_TEST(nh.empty());
|
||||
|
||||
BOOST_TEST_EQ(key::count_, expected_key_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class UnorderedMap> void test_map_non_transparent_extract()
|
||||
{
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename UnorderedMap::node_type node_type;
|
||||
typedef typename UnorderedMap::const_iterator const_iterator;
|
||||
typedef std::pair<const_iterator, const_iterator> const_iterator_pair;
|
||||
@@ -1441,8 +1475,10 @@ template <class UnorderedMap> void test_map_non_transparent_extract()
|
||||
++key_count;
|
||||
BOOST_TEST(nh.empty());
|
||||
BOOST_TEST_EQ(key::count_, key_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
transparent_unordered_set::node_type set_extract_overload_compile_test()
|
||||
{
|
||||
convertible_to_iterator<transparent_unordered_set> c;
|
||||
@@ -1480,9 +1516,11 @@ multiset_extract_const_overload_compile_test()
|
||||
pos = c;
|
||||
return set.extract(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class UnorderedSet> void test_set_transparent_extract()
|
||||
{
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename UnorderedSet::node_type node_type;
|
||||
|
||||
count_reset();
|
||||
@@ -1526,10 +1564,12 @@ template <class UnorderedSet> void test_set_transparent_extract()
|
||||
BOOST_TEST_EQ(set.size(), set_size);
|
||||
|
||||
BOOST_TEST_EQ(key::count_, expected_key_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class UnorderedSet> void test_set_non_transparent_extract()
|
||||
{
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef typename UnorderedSet::node_type node_type;
|
||||
|
||||
count_reset();
|
||||
@@ -1583,13 +1623,22 @@ template <class UnorderedSet> void test_set_non_transparent_extract()
|
||||
BOOST_TEST_EQ(set.size(), set_size);
|
||||
|
||||
BOOST_TEST_EQ(key::count_, key_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual> struct map_type
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_map<Key, T, Hash, KeyEqual> type;
|
||||
#else
|
||||
typedef boost::unordered_map<Key, T, Hash, KeyEqual> type;
|
||||
#endif
|
||||
};
|
||||
|
||||
void test_unordered_map()
|
||||
{
|
||||
{
|
||||
typedef boost::unordered_map<key, int, transparent_hasher,
|
||||
transparent_key_equal>
|
||||
typedef map_type<key, int, transparent_hasher, transparent_key_equal>::type
|
||||
unordered_map;
|
||||
|
||||
test_map_transparent_count<unordered_map>();
|
||||
@@ -1602,7 +1651,7 @@ void test_unordered_map()
|
||||
{
|
||||
// non-transparent Hash, non-transparent KeyEqual
|
||||
//
|
||||
typedef boost::unordered_map<key, int, hasher, key_equal> unordered_map;
|
||||
typedef map_type<key, int, hasher, key_equal>::type unordered_map;
|
||||
|
||||
test_map_non_transparent_count<unordered_map>();
|
||||
test_map_non_transparent_find<unordered_map>();
|
||||
@@ -1614,7 +1663,7 @@ void test_unordered_map()
|
||||
{
|
||||
// transparent Hash, non-transparent KeyEqual
|
||||
//
|
||||
typedef boost::unordered_map<key, int, transparent_hasher, key_equal>
|
||||
typedef map_type<key, int, transparent_hasher, key_equal>::type
|
||||
unordered_map;
|
||||
|
||||
test_map_non_transparent_count<unordered_map>();
|
||||
@@ -1627,7 +1676,7 @@ void test_unordered_map()
|
||||
{
|
||||
// non-transparent Hash, transparent KeyEqual
|
||||
//
|
||||
typedef boost::unordered_map<key, int, hasher, transparent_key_equal>
|
||||
typedef map_type<key, int, hasher, transparent_key_equal>::type
|
||||
unordered_map;
|
||||
|
||||
test_map_non_transparent_count<unordered_map>();
|
||||
@@ -1638,6 +1687,7 @@ void test_unordered_map()
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
void test_unordered_multimap()
|
||||
{
|
||||
{
|
||||
@@ -1691,11 +1741,21 @@ void test_unordered_multimap()
|
||||
test_map_non_transparent_extract<unordered_multimap>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Key, class Hash, class KeyEqual> struct set_type
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
typedef boost::unordered_flat_set<Key, Hash, KeyEqual> type;
|
||||
#else
|
||||
typedef boost::unordered_set<Key, Hash, KeyEqual> type;
|
||||
#endif
|
||||
};
|
||||
|
||||
void test_unordered_set()
|
||||
{
|
||||
{
|
||||
typedef boost::unordered_set<key, transparent_hasher, transparent_key_equal>
|
||||
typedef set_type<key, transparent_hasher, transparent_key_equal>::type
|
||||
unordered_set;
|
||||
|
||||
test_set_transparent_count<unordered_set>();
|
||||
@@ -1708,7 +1768,7 @@ void test_unordered_set()
|
||||
{
|
||||
// non-transparent Hash, non-transparent KeyEqual
|
||||
//
|
||||
typedef boost::unordered_set<key, hasher, key_equal> unordered_set;
|
||||
typedef set_type<key, hasher, key_equal>::type unordered_set;
|
||||
|
||||
test_set_non_transparent_count<unordered_set>();
|
||||
test_set_non_transparent_find<unordered_set>();
|
||||
@@ -1720,8 +1780,7 @@ void test_unordered_set()
|
||||
{
|
||||
// transparent Hash, non-transparent KeyEqual
|
||||
//
|
||||
typedef boost::unordered_set<key, transparent_hasher, key_equal>
|
||||
unordered_set;
|
||||
typedef set_type<key, transparent_hasher, key_equal>::type unordered_set;
|
||||
|
||||
test_set_non_transparent_count<unordered_set>();
|
||||
test_set_non_transparent_find<unordered_set>();
|
||||
@@ -1733,8 +1792,7 @@ void test_unordered_set()
|
||||
{
|
||||
// non-transparent Hash, transparent KeyEqual
|
||||
//
|
||||
typedef boost::unordered_set<key, hasher, transparent_key_equal>
|
||||
unordered_set;
|
||||
typedef set_type<key, hasher, transparent_key_equal>::type unordered_set;
|
||||
|
||||
test_set_non_transparent_count<unordered_set>();
|
||||
test_set_non_transparent_find<unordered_set>();
|
||||
@@ -1744,6 +1802,7 @@ void test_unordered_set()
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
void test_unordered_multiset()
|
||||
{
|
||||
{
|
||||
@@ -1796,12 +1855,16 @@ void test_unordered_multiset()
|
||||
test_set_non_transparent_extract<unordered_set>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST (transparent_ops) {
|
||||
test_unordered_map();
|
||||
test_unordered_multimap();
|
||||
test_unordered_set();
|
||||
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
test_unordered_multimap();
|
||||
test_unordered_multiset();
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
Reference in New Issue
Block a user