mirror of
https://github.com/boostorg/core.git
synced 2025-06-25 20:11:33 +02:00
Compare commits
665 Commits
boost-1.72
...
develop
Author | SHA1 | Date | |
---|---|---|---|
65337d1af8 | |||
16d8f5f8ff | |||
58f469cd80 | |||
457d6a8ad0 | |||
e3d8de377b | |||
8d25b9ce54 | |||
6e05e5e764 | |||
7cb3e689e0 | |||
11d367377f | |||
f32cb2f696 | |||
21761b3f62 | |||
2e87ab53f7 | |||
8d5ee24c97 | |||
db59ef2a81 | |||
c48b7f269f | |||
4c74671f73 | |||
1e1ccb491e | |||
787b03ea9c | |||
b9a2221b3b | |||
cb603c9c6b | |||
24a8174ef1 | |||
7178a52909 | |||
9a3febf848 | |||
3e147e4ced | |||
1222948a8e | |||
749b6340b5 | |||
92f6cfb3cc | |||
ed452c57a3 | |||
78885aab8e | |||
8ebe2e7f57 | |||
32e6c30f4b | |||
cebfe007e8 | |||
3e16f3df14 | |||
e3a2e88e4c | |||
5e451b6c84 | |||
88a957b21c | |||
1bac0ccfd1 | |||
602961e526 | |||
366802b43c | |||
9dd0a8e1e4 | |||
622476533c | |||
a09ee19e3e | |||
040b018ce0 | |||
42d0c5954a | |||
76d0f22d3b | |||
243eec26fe | |||
44c32d7691 | |||
0ee7dc5910 | |||
9e9e6e3898 | |||
242b14bb69 | |||
76061d91d4 | |||
bda05a7812 | |||
d66b8c1c13 | |||
bd29e0dd15 | |||
72761e34e0 | |||
983234baee | |||
83a3a51bee | |||
acbeaae181 | |||
d01b4e94cc | |||
e22bd49fa7 | |||
c056f3dfc9 | |||
8b8944dd6e | |||
278d3f0060 | |||
3f36d507f2 | |||
a77338b1cd | |||
a8c757ddf2 | |||
98a055cf34 | |||
074a467d9d | |||
965508d9e1 | |||
0a238bb30d | |||
d03e58b77e | |||
f774295cdb | |||
b18495fe35 | |||
c928c844da | |||
0a42ddabef | |||
04cc766db3 | |||
aa01ad8bf0 | |||
442e36f652 | |||
03040c7f5c | |||
8b31acf9a4 | |||
fd01cf788c | |||
151d0c4143 | |||
31117ef800 | |||
25b0defdeb | |||
541745ea24 | |||
083b41c17e | |||
a973490f53 | |||
5f825106c7 | |||
8cc2fdad76 | |||
0fb4d92d83 | |||
76401063a6 | |||
c4bb59617c | |||
2d7e036416 | |||
4a0df827c1 | |||
59c0fb69f0 | |||
2f092c62fe | |||
ccfee3f638 | |||
45e7e1a91a | |||
ce20d15048 | |||
b077925d77 | |||
61191fc0a1 | |||
0a35bb6a20 | |||
95f0b35c36 | |||
7b1d3718c1 | |||
80e12e1116 | |||
6f70ee87a3 | |||
db20a49e48 | |||
a57c78221b | |||
e4adc769aa | |||
8af04d101c | |||
cece8ca5b4 | |||
6c95750f37 | |||
a9f1407d84 | |||
db0fd77af1 | |||
7cbbb08e7b | |||
ba6360e8ed | |||
2a70a0f239 | |||
31a2f7fb6b | |||
0120dbfe65 | |||
5f6fe65eb2 | |||
c7134904e2 | |||
9fc2a2f1ac | |||
216999e552 | |||
66890c3f3d | |||
8d6d20059a | |||
ee596e3d37 | |||
de8fe4fad7 | |||
d4db3eccec | |||
3b96d237c0 | |||
0e71b6158d | |||
23ef6d3531 | |||
e088fb8929 | |||
57151ab82e | |||
992326b1c8 | |||
4e769d1cdd | |||
bf17035a2d | |||
5a3b4df5de | |||
85527c4045 | |||
7ab05d5de0 | |||
266fbe6449 | |||
fd0de5f538 | |||
350526f7c7 | |||
06fef712c9 | |||
b7f7eb4f90 | |||
f41b8f38c4 | |||
b591214103 | |||
6b9f0cbf57 | |||
ecee9257d5 | |||
6c7edac9b1 | |||
049d3447ca | |||
b2fe98edf8 | |||
42c8898d24 | |||
f2eab6d6ff | |||
36fa78f53c | |||
97606908b7 | |||
5eb54d1d36 | |||
c91f8fabff | |||
5904fb5636 | |||
39978bde2b | |||
d5fa9ae50f | |||
2814b4ca1c | |||
c4e420f69d | |||
94628cb2f9 | |||
19f9aa93e1 | |||
2691efd1ca | |||
b6b1498275 | |||
379899ef15 | |||
3ab949d321 | |||
dbf0ea98b9 | |||
5afc91d52d | |||
f2a1532105 | |||
64e59db1f6 | |||
ceb4fff8fc | |||
0be25e19cc | |||
6debbeb377 | |||
4b859e3d39 | |||
38037b45f1 | |||
7664d7ab7e | |||
20d89b69db | |||
89c5a78129 | |||
249c5bece2 | |||
8977da6f50 | |||
edc0d935c0 | |||
7736b0b8ce | |||
90231ed7e0 | |||
1aa287e413 | |||
8c65a5b0e8 | |||
99515c341e | |||
42b3a3f111 | |||
c092532a71 | |||
f6193acbdf | |||
a504b356d4 | |||
bd1835f92f | |||
bfad92e307 | |||
ce93055f03 | |||
39cf1e65a3 | |||
3edd3aa982 | |||
c704d8b630 | |||
579a658129 | |||
4c7f35613e | |||
642a0cf70e | |||
ece7a9ad9c | |||
5632ee0367 | |||
8052abb15c | |||
d3ed836f75 | |||
c4777c309e | |||
2b3b97c633 | |||
ab455ab2f8 | |||
116c6830e0 | |||
d8cfc71073 | |||
dd85ed565e | |||
58fd395c51 | |||
992824c50b | |||
9d443cb094 | |||
7d67301bba | |||
e487fec094 | |||
0890785fec | |||
eda68d4086 | |||
8a8738a981 | |||
99f9654f18 | |||
1e84baeea3 | |||
1825265014 | |||
8caca51c4d | |||
2d302c1666 | |||
6299da9273 | |||
843e0f7bb0 | |||
ddc6cc25a9 | |||
86bf1d4aec | |||
75c765cc13 | |||
2286749f97 | |||
23fa5d30f3 | |||
d428335758 | |||
be8790115c | |||
2778c5cca6 | |||
d5b7c3c0dc | |||
db916e4673 | |||
3eaba7afc0 | |||
ad20fadde7 | |||
a67ec1f75c | |||
5e95d28eb6 | |||
65377a2e13 | |||
b407b5d87d | |||
013c7856ce | |||
1c79871f0f | |||
09f2aa123a | |||
9cbf3ac420 | |||
fd615f3bfe | |||
a7f76af262 | |||
860eed6baf | |||
66a742f41e | |||
2cc3e23447 | |||
00f4f11f14 | |||
3510f6244b | |||
89852794ca | |||
0ac87736f8 | |||
1fa592c9ec | |||
162a4e1d24 | |||
68f8f36b04 | |||
6fb57488a2 | |||
414dfb4668 | |||
1b3a907394 | |||
ab23246301 | |||
48bc47cce2 | |||
e3745b2072 | |||
4162dbed57 | |||
38937b0fa3 | |||
8503c536dc | |||
7100c05490 | |||
ac9d79992e | |||
b6c3190468 | |||
f941d2e1f7 | |||
c0e2211c2b | |||
eec8689d58 | |||
45e5b1ebcf | |||
8645bcb06e | |||
ebff02a932 | |||
42ed795866 | |||
0212774324 | |||
43d0da03f3 | |||
0011697492 | |||
d74140983d | |||
1e5c86eb9d | |||
00cc660f28 | |||
44610b65ba | |||
5e0ff1680f | |||
4defdfd233 | |||
c4deb479fd | |||
f326683d42 | |||
dbefea9631 | |||
a32c1ee7ac | |||
230dd83002 | |||
ec91f29d56 | |||
188ca25bf3 | |||
ed84fc4e23 | |||
622b7a398a | |||
35a4e09854 | |||
b7c987f83c | |||
89d8efb7ff | |||
f12eeb6b9f | |||
ad63dcda9f | |||
6a5f726602 | |||
cf619432a7 | |||
b38c148969 | |||
bae7c049b0 | |||
ea7b623b7d | |||
6ae6ff79f1 | |||
06976ccad7 | |||
65723e0e1f | |||
df3b9827cf | |||
392cc988dd | |||
0ef1c06fd8 | |||
0b9624d047 | |||
574c7cf86e | |||
6e6af5fc90 | |||
95f2a76c90 | |||
28d26d13f1 | |||
ac71c55b4e | |||
c83e682b7e | |||
7a79d17da2 | |||
02b3f91fc3 | |||
a2b37091eb | |||
78dd0cce2f | |||
a121ab0278 | |||
0e62373aa2 | |||
6da7958281 | |||
c8479b4eca | |||
f5ab83efe8 | |||
eb7bc1ff53 | |||
d038633f98 | |||
ac4bdcc4c5 | |||
85a3183c01 | |||
0c9675cf56 | |||
5abadf4472 | |||
6b3fb219cc | |||
febc195093 | |||
8985ce604e | |||
15c884438c | |||
15f7fb7eaa | |||
46f37b2f16 | |||
c1be2097d7 | |||
c8b989d80b | |||
74c770206a | |||
a1ad1784bf | |||
213e4695bf | |||
a4172b4319 | |||
e4fb94b73c | |||
ef3505db59 | |||
f94db671f6 | |||
7b45315af1 | |||
bdd4bf7d9a | |||
9f2cdfa7d2 | |||
964ef98eee | |||
f09ab90243 | |||
d2e897fd60 | |||
66f6ea594a | |||
6a91536da6 | |||
c3a398b9a0 | |||
e73e8bfc83 | |||
633a47f85b | |||
eae98e909e | |||
a581a42c4f | |||
e44781e290 | |||
11958e9568 | |||
56566d9abc | |||
9efeed68cb | |||
da3c89dc5b | |||
ba208ad7fc | |||
bbfa6344fa | |||
bf4354a3a4 | |||
a4b661068d | |||
8299d25eb2 | |||
847f9d43fe | |||
44e294fff1 | |||
b5f59858b9 | |||
bed07e7d5b | |||
971cda2e4c | |||
d81c61abb4 | |||
370a74c249 | |||
62d1b1bb59 | |||
bb99544852 | |||
9b5bf05fae | |||
309a6bb797 | |||
9d1b59ec6c | |||
12f5f51427 | |||
0565456622 | |||
fda0f87576 | |||
e9718374ac | |||
79b7c49fb3 | |||
585ac9ace1 | |||
493832a570 | |||
8942e8ecc9 | |||
cbf03c4b9c | |||
5cf3569218 | |||
d5bd40e528 | |||
0e57df5aab | |||
62b23df9ef | |||
fdf1ed78a7 | |||
e02c333706 | |||
b677d1eeae | |||
0f7d02de01 | |||
773499db5e | |||
ce912859aa | |||
bfeee019dd | |||
220d4ae0a9 | |||
5d7b469e29 | |||
3cec508460 | |||
a47fac1449 | |||
7340f123fe | |||
038064e824 | |||
52c58efc36 | |||
15fdc0ab39 | |||
b520289660 | |||
9b22937647 | |||
903d44c0c5 | |||
88eee0c628 | |||
54965f567d | |||
c43a172ded | |||
ddf9b5087b | |||
d17313d407 | |||
c8b860704e | |||
e9ffc4336c | |||
a121d5a000 | |||
5c82e38c93 | |||
db15c7419d | |||
62e9d9b868 | |||
b01f2fe4d2 | |||
408cd96595 | |||
9f2ec3bfca | |||
63f3a97a15 | |||
b70bbf14db | |||
b251310a8f | |||
969a201c75 | |||
b9f1b9f39a | |||
3d4eb536cd | |||
a51364c5d3 | |||
ab3950fdfb | |||
fe9c0164c0 | |||
8ec0e7f68a | |||
85e24f0483 | |||
be820fea2e | |||
af3e6a667b | |||
c3cfe7a861 | |||
d87766a768 | |||
706747ab08 | |||
41c3b6a7dd | |||
8223ff03e4 | |||
18334b1614 | |||
df65ea6600 | |||
d1ad50cefb | |||
09870f0739 | |||
95e64ef71f | |||
673e3c302c | |||
a8e7a3395e | |||
09044f58d6 | |||
f9fa1772f2 | |||
c7dfa29f29 | |||
93c18fb937 | |||
c005ad5e55 | |||
8cf4d16297 | |||
0deaa2d502 | |||
22de922125 | |||
3ec157eb6f | |||
531726eb09 | |||
31a9336778 | |||
75fc48ad32 | |||
87c21a23bb | |||
3e9cc2153b | |||
98630095f3 | |||
6985b1ae25 | |||
8ab119135c | |||
1fd2cadddd | |||
bb0c6381f6 | |||
4f6f7c3799 | |||
cd1a8fd238 | |||
b0b48c5783 | |||
ccdf5ce031 | |||
b3906601f7 | |||
f833040d48 | |||
3b5595e940 | |||
b93317815c | |||
01bd23df5d | |||
36cec9a5cc | |||
290340fd27 | |||
003c7365bc | |||
31e2caef12 | |||
042bb98142 | |||
c65c05c006 | |||
1aa8341bd7 | |||
e206cddc6f | |||
c8b55f1bde | |||
62ba7ca18b | |||
964dfe2b74 | |||
016ae92ecf | |||
7d05dfa87d | |||
95924b1329 | |||
5e382efa84 | |||
e260bb865d | |||
f884833b42 | |||
8265fe6405 | |||
f7b04afe4d | |||
2c1eb07a68 | |||
a5cbddc466 | |||
91a64b3bcf | |||
a039f8c318 | |||
bebb7349ba | |||
dc6e3261ec | |||
15a7d84858 | |||
06023d4ffe | |||
3e0bc52c32 | |||
b83f27a9e0 | |||
578e3105b8 | |||
f34c4986c1 | |||
cfd469d858 | |||
b1e01b53f3 | |||
177c093151 | |||
cffaabead8 | |||
2715f9b5d8 | |||
8043bafb6b | |||
f6bdb17fd9 | |||
cd6847aee8 | |||
9ff312e2fb | |||
494927312d | |||
df91243a1d | |||
f4b3d5dba6 | |||
9f0b97c80b | |||
ce53cc1f8f | |||
8fad14b804 | |||
24b6d89e7f | |||
ffd79a28e1 | |||
aa97e418f2 | |||
f563d50d42 | |||
c55a20dff2 | |||
bc508f8b4c | |||
03c5481dd4 | |||
8e7ee90080 | |||
128d9314d6 | |||
012d96a72b | |||
27d700ec01 | |||
507c182f4c | |||
1a011cde56 | |||
71c3d320d5 | |||
b3fa7ca565 | |||
d3aa4a2f12 | |||
67107dbaf9 | |||
0b74f0d394 | |||
e53393357f | |||
7daee1d41b | |||
ddbaa242a9 | |||
86bff4c2d3 | |||
2e5ecbe6f6 | |||
1c43651533 | |||
afba04cf7f | |||
0ae16756eb | |||
2729beab83 | |||
71d60a3fb7 | |||
2642ad4562 | |||
f7c1f6c6ab | |||
10eb5cdf7c | |||
82a51aea40 | |||
5726534f6d | |||
a13a82f8c1 | |||
cb94f76a5e | |||
a6cab03127 | |||
fa82b680cf | |||
16e9536146 | |||
919b98d425 | |||
e8aa0c75b4 | |||
8bd2239b0b | |||
c838ebc003 | |||
aca46fae91 | |||
409c809cd8 | |||
dc8aa5eb39 | |||
26728848b4 | |||
3e41929dfb | |||
579cb8f7f3 | |||
3b14a3677d | |||
26991f0c75 | |||
cc877e6b5b | |||
123b567051 | |||
a47eebf41a | |||
045487ba96 | |||
804c5b250d | |||
bee040b8cc | |||
c307f86520 | |||
0364b64927 | |||
a04803b6cb | |||
88896d0805 | |||
bff4172486 | |||
ea0b1dc8a9 | |||
3d6683edb5 | |||
72089753f7 | |||
156a016865 | |||
0dcd164a12 | |||
54671134ae | |||
7bc2873e38 | |||
ca4893063f | |||
dcc04c5508 | |||
484487f958 | |||
503d035b7f | |||
35a025d59b | |||
c6d72da515 | |||
f96fb31850 | |||
b414be98c9 | |||
544fd495e5 | |||
e155e13084 | |||
6e36923915 | |||
b67cce85c8 | |||
376aa7aa31 | |||
65901249d5 | |||
1c16d5ed87 | |||
27715ed01a | |||
9f2dbba2fc | |||
0159b6d8e5 | |||
0dbd5aaadd | |||
34373b0127 | |||
6a33e879dd | |||
15db54983b | |||
fa6e38a9aa | |||
38f827e092 | |||
2b102e7357 | |||
9c33851420 | |||
fb593cbbc8 | |||
032ce991fb | |||
6444de7098 | |||
d3a64554f4 | |||
a57c1e0a80 | |||
e9ff763d79 | |||
6069fea76d | |||
3ca745f400 | |||
94def8a3a6 | |||
295b72cbc0 | |||
eb86df4a04 | |||
0a6b8e667b | |||
4d08e709fe | |||
12ff209bf7 | |||
bb0ef6d41e | |||
2dd51f248b | |||
8fe9805792 | |||
6624532550 | |||
c31e23b362 | |||
690514e87c | |||
5a5d2adda0 | |||
10c01d0d56 | |||
27d8ef1286 | |||
b5c2726d1b | |||
0eecbda0b1 | |||
2a471c3417 | |||
5ca752323f | |||
13e9d3d4d9 | |||
f3cd812ccb | |||
8f2841de83 | |||
bf5778403e | |||
fc285464aa | |||
750625272f | |||
bda2b9b4b1 | |||
ac4c781cac | |||
72ca0d8664 | |||
253b07f630 | |||
e59271fdc2 | |||
bc82adcd0b | |||
868cb07578 | |||
38f71361fb | |||
6d62fb5f5e | |||
0d71f42365 | |||
080e8581d5 |
437
.drone.jsonnet
Normal file
437
.drone.jsonnet
Normal file
@ -0,0 +1,437 @@
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
local library = "core";
|
||||
|
||||
local triggers =
|
||||
{
|
||||
branch: [ "master", "develop", "feature/*" ]
|
||||
};
|
||||
|
||||
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
|
||||
local asan = { ASAN: '1' };
|
||||
|
||||
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "linux",
|
||||
arch: arch
|
||||
},
|
||||
steps:
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'set -e',
|
||||
'uname -a',
|
||||
'echo $DRONE_STAGE_MACHINE',
|
||||
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
|
||||
] +
|
||||
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
|
||||
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "exec",
|
||||
trigger: triggers,
|
||||
platform: {
|
||||
"os": "darwin",
|
||||
"arch": arch
|
||||
},
|
||||
node: {
|
||||
"os": osx_version
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
name: "everything",
|
||||
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
|
||||
commands:
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "windows",
|
||||
arch: arch
|
||||
},
|
||||
"steps":
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'cmd /C .drone\\\\drone.bat ' + library,
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
[
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 4.4",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.4', CXXSTD: '98,0x' },
|
||||
"g++-4.4",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 4.6 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.6', CXXSTD: '98,0x', ADDRMD: '32,64' },
|
||||
"g++-4.6-multilib",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 4.7 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.7', CXXSTD: '98,0x', ADDRMD: '32,64' },
|
||||
"g++-4.7-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 4.8 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '03,11', ADDRMD: '32,64' },
|
||||
"g++-4.8-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 4.9 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '03,11', ADDRMD: '32,64' },
|
||||
"g++-4.9-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 5* 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 GCC 6 32/64",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '03,11,14', ADDRMD: '32,64' },
|
||||
"g++-6-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 GCC 7* 32/64",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 GCC 8 32/64",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '03,11,14,17', ADDRMD: '32,64' },
|
||||
"g++-8-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* 32/64",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* ARM64",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a' },
|
||||
arch="arm64",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* S390x",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a' },
|
||||
arch="s390x",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 10 32/64",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14,17,20', ADDRMD: '32,64' },
|
||||
"g++-10-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 GCC 11* 32/64",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 GCC 12 32/64",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32,64' },
|
||||
"g++-12-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 13* 32/64",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 32 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 64 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 32 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 64 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.5",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '03,11' },
|
||||
"clang-3.5",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.6",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '03,11,14' },
|
||||
"clang-3.6",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.7",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '03,11,14' },
|
||||
"clang-3.7",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.8",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '03,11,14' },
|
||||
"clang-3.8",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 Clang 3.9",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-3.9', CXXSTD: '03,11,14' },
|
||||
"clang-3.9",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 Clang 4.0",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-4.0', CXXSTD: '03,11,14' },
|
||||
"clang-4.0",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 Clang 5.0",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '03,11,14,1z' },
|
||||
"clang-5.0",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 Clang 6.0",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-6.0', CXXSTD: '03,11,14,17' },
|
||||
"clang-6.0",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 7",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '03,11,14,17' },
|
||||
"clang-7",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 8",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '03,11,14,17' },
|
||||
"clang-8",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 9",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '03,11,14,17,2a' },
|
||||
"clang-9",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 10",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '03,11,14,17,2a' },
|
||||
"clang-10",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 11",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '03,11,14,17,2a' },
|
||||
"clang-11",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 12",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '03,11,14,17,2a' },
|
||||
"clang-12",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 13",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '03,11,14,17,20' },
|
||||
"clang-13",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 14",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20,2b' },
|
||||
"clang-14",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 15",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '03,11,14,17,20,2b' },
|
||||
"clang-15",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 16",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '03,11,14,17,20,2b' },
|
||||
"clang-16",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 17",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '03,11,14,17,20,2b' },
|
||||
"clang-17",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 18 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '03,11,14,17,20,2b' } + ubsan,
|
||||
"clang-18",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 18 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '03,11,14,17,20,2b' } + asan,
|
||||
"clang-18",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.10 Clang 19",
|
||||
"cppalliance/droneubuntu2410:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-19', CXXSTD: '03,11,14,17,20,2b' },
|
||||
"clang-19",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + ubsan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 12.4 Xcode 13.4.1 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,17,20,2b' } + ubsan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 12.4 Xcode 13.4.1 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,17,20,2b' } + asan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2015 msvc-14.0",
|
||||
"cppalliance/dronevs2015",
|
||||
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', B2_DONT_EMBED_MANIFEST: '1' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2017 msvc-14.1",
|
||||
"cppalliance/dronevs2017",
|
||||
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2019 msvc-14.2",
|
||||
"cppalliance/dronevs2019",
|
||||
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2022 msvc-14.3",
|
||||
"cppalliance/dronevs2022:1",
|
||||
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest', ADDRMD: '32,64' },
|
||||
),
|
||||
]
|
23
.drone/drone.bat
Normal file
23
.drone/drone.bat
Normal file
@ -0,0 +1,23 @@
|
||||
@REM Copyright 2022 Peter Dimov
|
||||
@REM Distributed under the Boost Software License, Version 1.0.
|
||||
@REM https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@ECHO ON
|
||||
|
||||
set LIBRARY=%1
|
||||
set DRONE_BUILD_DIR=%CD%
|
||||
|
||||
set BOOST_BRANCH=develop
|
||||
if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init tools/boostdep
|
||||
xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\
|
||||
python tools/boostdep/depinst/depinst.py -I examples %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
|
25
.drone/drone.sh
Executable file
25
.drone/drone.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
set -ex
|
||||
export PATH=~/.local/bin:/usr/local/bin:$PATH
|
||||
|
||||
DRONE_BUILD_DIR=$(pwd)
|
||||
|
||||
BOOST_BRANCH=develop
|
||||
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
|
||||
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init tools/boostdep
|
||||
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
|
||||
python tools/boostdep/depinst/depinst.py -I examples $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
|
1118
.github/workflows/ci.yml
vendored
Normal file
1118
.github/workflows/ci.yml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
344
.travis.yml
344
.travis.yml
@ -1,344 +0,0 @@
|
||||
# Copyright 2016-2019 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
dist: trusty
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /feature\/.*/
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
|
||||
exclude:
|
||||
- env: BOGUS_JOB=true
|
||||
|
||||
include:
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.4
|
||||
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.4
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.6
|
||||
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.7
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.8
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.9
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-5
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-6
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-8
|
||||
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-9
|
||||
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-8
|
||||
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.5
|
||||
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.5
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.6
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.8
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.9
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-4.0
|
||||
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-4.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-5.0
|
||||
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-5.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-6.0
|
||||
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-6.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-6.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-7
|
||||
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-7
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-8
|
||||
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-8
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang++-9
|
||||
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-6.0
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-6.0
|
||||
- libstdc++-5-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-6.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-libc++
|
||||
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
- libc++abi-dev
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-libc++
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
- libc++abi-dev
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
osx_image: xcode7.3
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
osx_image: xcode8.3
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
osx_image: xcode9.4
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
osx_image: xcode10.1
|
||||
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: CMAKE_SUBDIR_TEST=1
|
||||
script:
|
||||
- cd libs/core/test/cmake_subdir_test && mkdir __build__ && cd __build__
|
||||
- cmake ..
|
||||
- cmake --build .
|
||||
- cmake --build . --target check
|
||||
|
||||
install:
|
||||
- BOOST_BRANCH=develop
|
||||
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
|
||||
- cd ..
|
||||
- git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule init libs/headers
|
||||
- git submodule init libs/assert
|
||||
- git submodule init libs/config
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/static_assert
|
||||
- git submodule init libs/throw_exception
|
||||
- git submodule init libs/type_traits
|
||||
- git submodule init tools/build
|
||||
- git submodule init tools/boost_install
|
||||
- git submodule update --jobs 4
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/core
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
- BUILD_JOBS=`(nproc || sysctl -n hw.ncpu) 2> /dev/null`
|
||||
- ./b2 -j $BUILD_JOBS libs/core/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
@ -1,13 +1,11 @@
|
||||
# Copyright 2018 Peter Dimov
|
||||
# Generated by `boostdep --cmake core`
|
||||
# Copyright 2020, 2021 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
# Partial (add_subdirectory only) and experimental CMake support
|
||||
# Subject to change; please do not rely on the contents of this file yet
|
||||
cmake_minimum_required(VERSION 3.5...3.20)
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(BoostCore LANGUAGES CXX)
|
||||
project(boost_core VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
add_library(boost_core INTERFACE)
|
||||
add_library(Boost::core ALIAS boost_core)
|
||||
@ -15,7 +13,24 @@ add_library(Boost::core ALIAS boost_core)
|
||||
target_include_directories(boost_core INTERFACE include)
|
||||
|
||||
target_link_libraries(boost_core
|
||||
INTERFACE
|
||||
Boost::assert
|
||||
Boost::config
|
||||
INTERFACE
|
||||
Boost::assert
|
||||
Boost::config
|
||||
Boost::static_assert
|
||||
Boost::throw_exception
|
||||
)
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.18 AND CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
|
||||
file(GLOB_RECURSE boost_core_IDEFILES CONFIGURE_DEPENDS include/*.hpp)
|
||||
source_group(TREE ${PROJECT_SOURCE_DIR}/include FILES ${boost_core_IDEFILES} PREFIX "Header Files")
|
||||
list(APPEND boost_core_IDEFILES extra/boost_core.natvis)
|
||||
target_sources(boost_core PRIVATE ${boost_core_IDEFILES})
|
||||
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
endif()
|
||||
|
10
README.md
10
README.md
@ -8,12 +8,12 @@ The criteria for inclusion is that the utility component be:
|
||||
* used by other Boost libraries, and
|
||||
* not dependent on any other Boost modules except Core itself, Config, Assert, Static Assert, or Predef.
|
||||
|
||||
### CI Status
|
||||
### Build Status
|
||||
|
||||
Branch | Travis | Appveyor
|
||||
---------|--------|---------
|
||||
Develop | [](https://travis-ci.org/boostorg/core) | [](https://ci.appveyor.com/project/pdimov/core)
|
||||
Master | [](https://travis-ci.org/boostorg/core) | [](https://ci.appveyor.com/project/pdimov/core)
|
||||
Branch | GitHub Actions | AppVeyor | Test Matrix | Dependencies |
|
||||
---------|----------------|--------- | ----------- | ------------ |
|
||||
Develop | [](https://github.com/boostorg/filesystem/actions?query=branch%3Adevelop) | [](https://ci.appveyor.com/project/pdimov/core) | [](http://www.boost.org/development/tests/develop/developer/core.html) | [](https://pdimov.github.io/boostdep-report/develop/core.html)
|
||||
Master | [](https://github.com/boostorg/filesystem/actions?query=branch%3Amaster) | [](https://ci.appveyor.com/project/pdimov/core) | [](http://www.boost.org/development/tests/master/developer/core.html) | [](https://pdimov.github.io/boostdep-report/master/core.html)
|
||||
|
||||
### Directories
|
||||
|
||||
|
65
appveyor.yml
65
appveyor.yml
@ -1,4 +1,4 @@
|
||||
# Copyright 2016-2019 Peter Dimov
|
||||
# Copyright 2016-2021 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -16,20 +16,28 @@ environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
|
||||
ADDRMD: 32
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-12.0,msvc-14.0
|
||||
ADDRMD: 32,64
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1,clang-win
|
||||
TOOLSET: msvc-14.1
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17
|
||||
|
||||
# clang-win 32 bit fails to link with "unable to load mspdbcore.dll (error code: 126)"
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: clang-win
|
||||
ADDRMD: 64
|
||||
CXXSTD: 14,17,latest
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
TOOLSET: msvc-14.2
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17
|
||||
TOOLSET: clang-win
|
||||
ADDRMD: 64
|
||||
CXXSTD: 14,17,latest
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
@ -56,25 +64,25 @@ environment:
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
CMAKE: 1
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
CMAKE_SUBDIR: 1
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
CMAKE_INSTALL: 1
|
||||
|
||||
install:
|
||||
- set GIT_FETCH_JOBS=8
|
||||
- set BOOST_BRANCH=develop
|
||||
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
- cd ..
|
||||
- git clone -b %BOOST_BRANCH% https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule init libs/headers
|
||||
- git submodule init libs/assert
|
||||
- git submodule init libs/config
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/static_assert
|
||||
- git submodule init libs/throw_exception
|
||||
- git submodule init libs/type_traits
|
||||
- git submodule init tools/build
|
||||
- git submodule init tools/boost_install
|
||||
- git submodule update --jobs 4
|
||||
- git submodule update --init tools/boostdep
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\core\
|
||||
- python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" core
|
||||
- cmd /c bootstrap
|
||||
- b2 headers
|
||||
- b2 -d0 headers
|
||||
|
||||
build: off
|
||||
|
||||
@ -82,4 +90,27 @@ test_script:
|
||||
- PATH=%ADDPATH%%PATH%
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
- b2 -j %NUMBER_OF_PROCESSORS% libs/core/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release
|
||||
- if "%CMAKE%%CMAKE_SUBDIR%%CMAKE_INSTALL%" == "" b2 -j %NUMBER_OF_PROCESSORS% libs/core/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
|
||||
|
||||
- if not "%CMAKE%" == "" mkdir __build__ && cd __build__
|
||||
- if not "%CMAKE%" == "" cmake -DBUILD_TESTING=ON -DBOOST_INCLUDE_LIBRARIES=core ..
|
||||
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config Debug & ctest --output-on-failure --no-tests=error -j 3 -C Debug
|
||||
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config Release & ctest --output-on-failure --no-tests=error -j 3 -C Release
|
||||
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config MinSizeRel & ctest --output-on-failure --no-tests=error -j 3 -C MinSizeRel
|
||||
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config RelWithDebInfo & ctest --output-on-failure --no-tests=error -j 3 -C RelWithDebInfo
|
||||
|
||||
- if not "%CMAKE_SUBDIR%" == "" cd libs/core/test/cmake_subdir_test && mkdir __build__ && cd __build__
|
||||
- if not "%CMAKE_SUBDIR%" == "" cmake ..
|
||||
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config Debug && cmake --build . --target check --config Debug
|
||||
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config Release && cmake --build . --target check --config Release
|
||||
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config MinSizeRel && cmake --build . --target check --config MinSizeRel
|
||||
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config RelWithDebInfo && cmake --build . --target check --config RelWithDebInfo
|
||||
|
||||
- if not "%CMAKE_INSTALL%" == "" mkdir __build__ && cd __build__
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake -DBOOST_INCLUDE_LIBRARIES=core -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake --build . --target install --config Debug
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake --build . --target install --config Release
|
||||
- if not "%CMAKE_INSTALL%" == "" cd ../libs/core/test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake --build . --config Debug && cmake --build . --target check --config Debug
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake --build . --config Release && cmake --build . --target check --config Release
|
||||
|
23
build.jam
Normal file
23
build.jam
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright 2023-2024 René Ferdinand Rivera Morell
|
||||
# Copyright 2024 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
require-b2 5.2 ;
|
||||
|
||||
constant boost_dependencies :
|
||||
/boost/assert//boost_assert
|
||||
/boost/config//boost_config
|
||||
/boost/static_assert//boost_static_assert
|
||||
/boost/throw_exception//boost_throw_exception
|
||||
;
|
||||
|
||||
project /boost/core ;
|
||||
|
||||
explicit
|
||||
[ alias boost_core : : : : <include>include <library>$(boost_dependencies) ]
|
||||
[ alias all : boost_core test ]
|
||||
;
|
||||
|
||||
call-if : boost-library core
|
||||
;
|
@ -5,12 +5,15 @@
|
||||
# Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
# or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import project ;
|
||||
import doxygen ;
|
||||
import quickbook ;
|
||||
|
||||
path-constant INCLUDES : ../include ;
|
||||
|
||||
doxygen ref_reference
|
||||
:
|
||||
[ glob ../../../boost/core/ref.hpp ]
|
||||
$(INCLUDES)/boost/core/ref.hpp
|
||||
:
|
||||
<doxygen:param>ENABLE_PREPROCESSING=YES
|
||||
<doxygen:param>EXPAND_ONLY_PREDEF=YES
|
||||
|
33
doc/alignof.qbk
Normal file
33
doc/alignof.qbk
Normal file
@ -0,0 +1,33 @@
|
||||
[/
|
||||
Copyright 2023 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:alignof alignof]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/alignof.hpp>]
|
||||
|
||||
The header `<boost/core/alignof.hpp>` defines the macro `BOOST_CORE_ALIGNOF`,
|
||||
a portable equivalent of the `alignof` operator from C++11.
|
||||
|
||||
[section Example]
|
||||
|
||||
``
|
||||
#include <boost/core/alignof.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
constexpr std::size_t alignment_of_double = BOOST_CORE_ALIGNOF(double);
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
@ -1,149 +0,0 @@
|
||||
[/
|
||||
Copyright 2019 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:alloc_construct alloc_construct, alloc_destroy]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
The header <boost/core/alloc_construct.hpp> provides function templates
|
||||
`alloc_construct`, `alloc_construct_n`, `alloc_destroy`, and `alloc_destroy_n`
|
||||
for allocator aware and exception safe construction and destruction of objects
|
||||
and arrays.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Example]
|
||||
|
||||
The following example allocates storage for an array of `n` elements of `T`
|
||||
using an allocator `a` and constructs `T` elements in that storage. If any
|
||||
exception was thrown during construction of an element, the constructed
|
||||
elements are destroyed in reverse order.
|
||||
|
||||
```
|
||||
template<class A>
|
||||
auto create(A& a, std::size_t n)
|
||||
{
|
||||
auto p = a.allocate(n);
|
||||
try {
|
||||
boost::alloc_construct_n(a, boost::to_address(p), n);
|
||||
} catch (...) {
|
||||
a.deallocate(p, n);
|
||||
throw;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class A, class T>
|
||||
void alloc_destroy(A& a, T* p);
|
||||
|
||||
template<class A, class T>
|
||||
void alloc_destroy_n(A& a, T* p, std::size_t n);
|
||||
|
||||
template<class A, class T, class Args>
|
||||
void alloc_construct(A& a, T* p, Args&&... args);
|
||||
|
||||
template<class A, class T>
|
||||
void alloc_construct_n(A& a, T* p, std::size_t n);
|
||||
|
||||
template<class A, class T>
|
||||
void alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m);
|
||||
|
||||
template<class A, class T, class I>
|
||||
void alloc_construct_n(A& a, T* p, std::size_t n, I begin);
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
[section Functions]
|
||||
|
||||
[variablelist
|
||||
[[`template<class A, class T> void alloc_destroy(A& a, T* p);`]
|
||||
[[variablelist
|
||||
[[Requires][`A` is an /Allocator/]]
|
||||
[[Effects][`std::allocator_traits<A>::destroy(a, p)`.]]]]]
|
||||
[[`template<class A, class T> void alloc_destroy_n(A& a, T* p,
|
||||
std::size_t n);`]
|
||||
[[variablelist
|
||||
[[Requires][`A` is an /Allocator/]]
|
||||
[[Effects]
|
||||
[Destroys each `i`-th element in reverse order by calling
|
||||
`std::allocator_traits<A>::destroy(a, &p[i])`.]]]]]
|
||||
[[`template<class A, class T, class Args> void alloc_construct(A& a, T* p,
|
||||
Args&&... args);`]
|
||||
[[variablelist
|
||||
[[Requires][`A` is an /Allocator/]]
|
||||
[[Effects]
|
||||
[`std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...)`.]]]]]
|
||||
[[`template<class A, class T> void alloc_construct_n(A& a, T* p,
|
||||
std::size_t n);`]
|
||||
[[variablelist
|
||||
[[Requires][`A` is an /Allocator/]]
|
||||
[[Effects]
|
||||
[Constructs each `i`-th element in order by calling
|
||||
`std::allocator_traits<A>::construct(a, &p[i])`.]]
|
||||
[[Remarks]
|
||||
[If an exception is thrown destroys each already constructed `j`-th element in
|
||||
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]
|
||||
[[`template<class A, class T> void alloc_construct_n(A& a, T* p, std::size_t n,
|
||||
const T* l, std::size_t m);`]
|
||||
[[variablelist
|
||||
[[Requires][`A` is an /Allocator/]]
|
||||
[[Effects]
|
||||
[Constructs each `i`-th element in order by calling
|
||||
`std::allocator_traits<A>::construct(a, &p[i], l[i % m])`.]]
|
||||
[[Remarks]
|
||||
[If an exception is thrown destroys each already constructed `j`-th element in
|
||||
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]
|
||||
[[`template<class A, class T, class I> void alloc_construct_n(A& a, T* p,
|
||||
std::size_t n, I begin);`]
|
||||
[[variablelist
|
||||
[[Requires]
|
||||
[[itemized_list
|
||||
[`A` is an /Allocator/][`I` is an /InputIterator/]]]]
|
||||
[[Effects]
|
||||
[Constructs each `i`-th element in order by calling
|
||||
`std::allocator_traits<A>::construct(a, &p[i], *begin++])`.]]
|
||||
[[Remarks]
|
||||
[If an exception is thrown destroys each already constructed `j`-th element in
|
||||
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Compatibility]
|
||||
|
||||
When `BOOST_NO_CXX11_ALLOCATOR` is defined, and the C++11 allocator model is
|
||||
not supported, these functions invoke constructors and destructors directly
|
||||
without going through the supplied allocator.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Acknowledgments]
|
||||
|
||||
Glen Fernandes originally implemented this functionality in Boost.Smart_Ptr and
|
||||
later moved these functions to Boost.Core for use in other Boost libraries,
|
||||
such as Boost.Multi_Array and Boost.Histogram.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
302
doc/allocator_access.qbk
Normal file
302
doc/allocator_access.qbk
Normal file
@ -0,0 +1,302 @@
|
||||
[/
|
||||
Copyright 2020-2022 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section allocator_access]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
The header `<boost/core/allocator_access.hpp>` provides the class and function
|
||||
templates to simplify allocator use. It provides the same functionality as the
|
||||
C++ standard library `std::allocator_traits` but with individual templates for
|
||||
each allocator feature.
|
||||
|
||||
It also adds additional functionality for allocator aware exception safe
|
||||
construction and destruction of arrays.
|
||||
|
||||
These facilities also simplify existing libraries by avoiding having to check
|
||||
for `BOOST_NO_CXX11_ALLOCATOR` and conditionally use `std::allocator_traits`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
|
||||
The following example shows these utilities used in the definition of
|
||||
an allocator-aware container class:
|
||||
|
||||
```
|
||||
template<class T, class A = boost::default_allocator<T> >
|
||||
class container
|
||||
: boost::empty_value<typename boost::allocator_rebind<A, T>::type> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef A allocator_type;
|
||||
typedef typename boost::allocator_size_type<A>::type size_type;
|
||||
typedef typename boost::allocator_difference_type<A>::type difference_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename boost::allocator_pointer<A>::type pointer;
|
||||
typedef typename boost::allocator_const_pointer<A>::type const_pointer;
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
In C++11 or above, aliases such as `boost::allocator_pointer_t<A>` can be used
|
||||
instead of `typename boost::allocator_pointer<A>::type`.
|
||||
|
||||
The following example allocates storage for an array of `n` elements of `T`
|
||||
using an allocator `a` and constructs `T` elements in that storage. If any
|
||||
exception was thrown during construction of an element, the constructed
|
||||
elements are destroyed in reverse order.
|
||||
|
||||
```
|
||||
template<class A>
|
||||
auto create(A& a, std::size_t n)
|
||||
{
|
||||
auto p = a.allocate(n);
|
||||
try {
|
||||
boost::allocator_construct_n(a, boost::to_address(p), n);
|
||||
} catch (...) {
|
||||
a.deallocate(p, n);
|
||||
throw;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class A>
|
||||
struct allocator_value_type;
|
||||
|
||||
template<class A>
|
||||
using allocator_value_type_t = typename allocator_value_type<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_pointer;
|
||||
|
||||
template<class A>
|
||||
using allocator_pointer_t = typename allocator_pointer<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_const_pointer;
|
||||
|
||||
template<class A>
|
||||
using allocator_const_pointer_t = typename allocator_const_pointer<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_void_pointer;
|
||||
|
||||
template<class A>
|
||||
using allocator_void_pointer_t = typename allocator_void_pointer<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_const_void_pointer;
|
||||
|
||||
template<class A>
|
||||
using allocator_const_void_pointer_t =
|
||||
typename allocator_const_void_pointer<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_difference_type;
|
||||
|
||||
template<class A>
|
||||
using allocator_difference_type_t =
|
||||
typename allocator_difference_type<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_size_type;
|
||||
|
||||
template<class A>
|
||||
using allocator_size_type_t = typename allocator_size_type<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_propagate_on_container_copy_assignment;
|
||||
|
||||
template<class A>
|
||||
using allocator_propagate_on_container_copy_assignment_t =
|
||||
typename allocator_propagate_on_container_copy_assignment<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_propagate_on_container_move_assignment;
|
||||
|
||||
template<class A>
|
||||
using allocator_propagate_on_container_move_assignment_t =
|
||||
typename allocator_propagate_on_container_move_assignment<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_propagate_on_container_swap;
|
||||
|
||||
template<class A>
|
||||
using allocator_propagate_on_container_swap_t =
|
||||
typename allocator_propagate_on_container_swap<A>::type;
|
||||
|
||||
template<class A>
|
||||
struct allocator_is_always_equal;
|
||||
|
||||
template<class A>
|
||||
using allocator_is_always_equal_t =
|
||||
typename allocator_is_always_equal<A>::type;
|
||||
|
||||
template<class A, class T>
|
||||
struct allocator_rebind;
|
||||
|
||||
template<class A, class T>
|
||||
using allocator_rebind_t = typename allocator_rebind<A, T>::type;
|
||||
|
||||
template<class A>
|
||||
allocator_pointer_t<A> allocator_allocate(A& a, allocator_size_type_t<A> n);
|
||||
|
||||
template<class A>
|
||||
allocator_pointer_t<A> allocator_allocate(A& a, allocator_size_type_t<A> n,
|
||||
allocator_const_void_pointer_t<A> h);
|
||||
|
||||
template<class A>
|
||||
void allocator_deallocate(A& a, allocator_pointer_t<A> p,
|
||||
allocator_size_type_t<A> n);
|
||||
|
||||
template<class A, class T, class... Args>
|
||||
void allocator_construct(A& a, T* p, Args&&... args);
|
||||
|
||||
template<class A, class T>
|
||||
void allocator_construct_n(A& a, T* p, std::size_t n);
|
||||
|
||||
template<class A, class T>
|
||||
void allocator_construct_n(A& a, T* p, std::size_t n, const T* l,
|
||||
std::size_t m);
|
||||
|
||||
template<class A, class T, class I>
|
||||
void allocator_construct_n(A& a, T* p, std::size_t n, I begin);
|
||||
|
||||
template<class A, class T>
|
||||
void allocator_destroy(A& a, T* p);
|
||||
|
||||
template<class A, class T>
|
||||
void allocator_destroy_n(A& a, T* p, std::size_t n);
|
||||
|
||||
template<class A>
|
||||
allocator_size_type_t<A> allocator_max_size(const A& a);
|
||||
|
||||
template<class A>
|
||||
A allocator_select_on_container_copy_construction(const A& a);
|
||||
|
||||
} // boost
|
||||
```
|
||||
|
||||
[section Types]
|
||||
|
||||
[variablelist
|
||||
[[`template<class A> struct allocator_value_type;`]
|
||||
[The member `type` is `A::value_type`.]]
|
||||
[[`template<class A> struct allocator_pointer;`]
|
||||
[The member `type` is `A::pointer` if valid, otherwise
|
||||
`allocator_value_type_t<A>*`.]]
|
||||
[[`template<class A> struct allocator_const_pointer;`]
|
||||
[The member `type` is `A::const_pointer` if valid, otherwise
|
||||
`pointer_traits<allocator_pointer_t<A> >::rebind<const
|
||||
allocator_value_type_t<A> >`.]]
|
||||
[[`template<class A> struct allocator_void_pointer;`]
|
||||
[The member `type` is `A::void_pointer` if valid, otherwise
|
||||
`pointer_traits<allocator_pointer_t<A> >::rebind<void>`.]]
|
||||
[[`template<class A> struct allocator_const_void_pointer;`]
|
||||
[The member `type` is `A::const_void_pointer` if valid, otherwise
|
||||
`pointer_traits<allocator_pointer_t<A> >::rebind<const void>`.]]
|
||||
[[`template<class A> struct allocator_difference_type;`]
|
||||
[The member `type` is `A::difference_type` if valid, otherwise
|
||||
`pointer_traits<allocator_pointer_t<A> >::difference_type`.]]
|
||||
[[`template<class A> struct allocator_size_type;`]
|
||||
[The member `type` is `A::size_type` if valid, otherwise
|
||||
`std::make_unsigned_t<allocator_difference_type_t<A> >`.]]
|
||||
[[`template<class A> struct allocator_propagate_on_container_copy_assignment;`]
|
||||
[The member `type` is `A::propagate_on_container_copy_assignment` if valid,
|
||||
otherwise `std::false_type`.]]
|
||||
[[`template<class A> struct allocator_propagate_on_container_move_assignment;`]
|
||||
[The member `type` is `A::propagate_on_container_move_assignment` if valid,
|
||||
otherwise `std::false_type`.]]
|
||||
[[`template<class A> struct allocator_propagate_on_container_swap;`]
|
||||
[The member `type` is `A::propagate_on_container_swap` if valid, otherwise
|
||||
`std::false_type`.]]
|
||||
[[`template<class A> struct allocator_is_always_equal;`]
|
||||
[The member `type` is `A::is_always_equal` if valid, otherwise
|
||||
`std::is_empty<A>::type`.]]
|
||||
[[`template<class A, class T> struct allocator_rebind;`]
|
||||
[The member `type` is `A::rebind<T>::other` if valid, otherwise `A<T, Args>`
|
||||
if this `A` is `A<U, Args>`.]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Functions]
|
||||
|
||||
[variablelist
|
||||
[[`template<class A>
|
||||
allocator_pointer_t<A> allocator_allocate(A& a, allocator_size_type_t<A> n);`]
|
||||
[Calls `a.allocate(n)`.]]
|
||||
[[`template<class A> allocator_pointer_t<A> allocator_allocate(A& a,
|
||||
allocator_size_type_t<A> n, allocator_const_void_pointer_t<A> hint);`]
|
||||
[Calls `a.allocate(n, hint)` if valid, otherwise calls `a.allocate(n)`.]]
|
||||
[[`template<class A> void allocator_deallocate(A& a, allocator_pointer_t<A> p,
|
||||
allocator_size_type_t<A> n);`]
|
||||
[Calls `a.deallocate(p, n)`.]]
|
||||
[[`template<class A, class T, class... Args>
|
||||
void allocator_construct(A& a, T*p, Args&&... args);`]
|
||||
[Calls `a.construct(p, std::forward<Args>(args)...)` if valid, otherwise calls
|
||||
`::new(static_cast<void*>(p)) T(std::forward<Args>(args)...)`.]]
|
||||
[[`template<class A, class T>
|
||||
void alloc_construct_n(A& a, T* p, std::size_t n);`]
|
||||
[Constructs each `i`-th element in order by calling
|
||||
`boost::allocator_construct(a, &p[i])`.
|
||||
If an exception is thrown destroys each already constructed `j`-th element in
|
||||
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
|
||||
[[`template<class A, class T>
|
||||
void alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m);`]
|
||||
[Constructs each `i`-th element in order by calling
|
||||
`boost::allocator_construct(a, &p[i], l[i % m])`.
|
||||
If an exception is thrown destroys each already constructed `j`-th element in
|
||||
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
|
||||
[[`template<class A, class T, class I>
|
||||
void alloc_construct_n(A& a, T* p, std::size_t n, I begin);`]
|
||||
[Constructs each `i`-th element in order by calling
|
||||
`boost::allocator_construct(a, &p[i], *begin++)`.
|
||||
If an exception is thrown destroys each already constructed `j`-th element in
|
||||
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
|
||||
[[`template<class A, class T> void allocator_destroy(A& a, T* p);`]
|
||||
[Calls `a.destroy(p)` if valid, otherwise calls `p->~T()`.]]
|
||||
[[`template<class A, class T>
|
||||
void allocator_destroy_n(A& a, T* p, std::size_t n);`]
|
||||
[Destroys each `i`-th element in reverse order by calling
|
||||
`boost::allocator_destroy(a, &p[i])`.]]
|
||||
[[`template<class A> allocator_size_type_t<A> allocator_max_size(const A& a);`]
|
||||
[Returns `a.max_size()` if valid, otherwise returns
|
||||
`std::numeric_limits<allocator_size_type_t<A> >::max() /
|
||||
sizeof(allocator_value_type_t<A>)`.]]
|
||||
[[`template<class A> A allocator_select_on_container_copy_construction(const
|
||||
A& a);`]
|
||||
[Returns `a.select_on_container_copy_construction()` if valid, otherwise
|
||||
returns `a`.]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Acknowledgements]
|
||||
|
||||
Glen Fernandes implemented the allocator access utilities.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
116
doc/allocator_traits.qbk
Normal file
116
doc/allocator_traits.qbk
Normal file
@ -0,0 +1,116 @@
|
||||
[/
|
||||
Copyright 2021 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:allocator_traits allocator_traits]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
This header <boost/core/allocator_traits.hpp> provides an implementation of the
|
||||
C++ standard library class template `allocator_traits` based on the facilities
|
||||
in [link core.allocator_access Allocator Access]. Users should still prefer the
|
||||
individual traits, but this utility exists to simplify migration.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class A>
|
||||
struct allocator_traits {
|
||||
using allocator_type = A;
|
||||
|
||||
using value_type = allocator_value_type_t<A>;
|
||||
|
||||
using pointer = allocator_pointer_t<A>;
|
||||
|
||||
using const_pointer = allocator_const_pointer_t<A>;
|
||||
|
||||
using void_pointer = allocator_void_pointer_t<A>;
|
||||
|
||||
using const_pointer = allocator_const_void_pointer_t<A>;
|
||||
|
||||
using difference_type = allocator_difference_type_t<A>;
|
||||
|
||||
using size_type = allocator_size_type_t<A>;
|
||||
|
||||
using propagate_on_container_copy_assignment =
|
||||
allocator_propagate_on_container_copy_assignment_t<A>;
|
||||
|
||||
using propagate_on_container_move_assignment =
|
||||
allocator_propagate_on_container_move_assignment_t<A>;
|
||||
|
||||
using propagate_on_container_swap =
|
||||
allocator_propagate_on_container_swap_t<A>;
|
||||
|
||||
using is_always_equal = allocator_is_always_equal_t<A>;
|
||||
|
||||
template<class T>
|
||||
using rebind_traits = allocator_traits<allocator_rebind_t<A, T> >;
|
||||
|
||||
static pointer allocate(A& a, size_type n);
|
||||
|
||||
static pointer allocate(A& a, size_type n, const_void_pointer h);
|
||||
|
||||
static void deallocate(A& a, pointer p, size_type n);
|
||||
|
||||
template<class T, class... Args>
|
||||
static void construct(A& a, T* p, Args&&... args);
|
||||
|
||||
static void destroy(A& a, T* p);
|
||||
|
||||
static size_type max_size(const A& a) noexcept;
|
||||
|
||||
static A select_on_container_copy_construction(const A& a);
|
||||
};
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
[section Static member functions]
|
||||
|
||||
[variablelist
|
||||
[[`static pointer allocate(A& a, size_type n);`]
|
||||
[Equivalent to: `return boost::allocator_allocate(a, n);`]]
|
||||
[[`static pointer allocate(A& a, size_type n, const_void_pointer h);`]
|
||||
[Equivalent to: `return boost::allocator_allocate(a, n, h);`]]
|
||||
[[`static void deallocate(A& a, pointer p, size_type n);`]
|
||||
[Equivalent to: `boost::allocator_deallocate(a, n, h);`]]
|
||||
[[`template<class T, class... Args>
|
||||
static void construct(A& a, T* p, Args&&... args);`]
|
||||
[Equivalent to:
|
||||
`boost::allocator_construct(a, p, std::forward<Args>(args)...);`]]
|
||||
[[`static void destroy(A& a, T* p);`]
|
||||
[Equivalent to: `boost::allocator_destroy(a, p);`]]
|
||||
[[`static size_type max_size(const A& a) noexcept;`]
|
||||
[Equivalent to: `return boost::allocator_max_size(a);`]]
|
||||
[[`static A select_on_container_copy_construction(const A& a);`]
|
||||
[Equivalent to:
|
||||
`return boost::allocator_select_on_container_copy_construction(a);`]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Notes]
|
||||
|
||||
# The member `rebind_alloc` is not provided for parity with C++03 where it is
|
||||
unimplementable. Instead of `allocator_traits<A>::rebind_alloc<U>` you can
|
||||
express the same with `allocator_traits<A>::rebind_traits<U>::allocator_type`
|
||||
or more simply with `allocator_rebind_t<A, U>`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
219
doc/bit.qbk
Normal file
219
doc/bit.qbk
Normal file
@ -0,0 +1,219 @@
|
||||
[/
|
||||
Copyright 2020 Peter Dimov
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
See accompanying file LICENSE_1_0.txt
|
||||
or copy at http://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:bit bit]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/bit.hpp>]
|
||||
|
||||
The header `<boost/core/bit.hpp>` implements, in a portable way,
|
||||
the C++20 `<bit>` header.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
// bit_cast
|
||||
|
||||
template<class To, class From>
|
||||
To bit_cast(From const& from) noexcept;
|
||||
|
||||
// byteswap
|
||||
|
||||
template<class T>
|
||||
constexpr T byteswap(T x) noexcept;
|
||||
|
||||
// Integral powers of 2
|
||||
|
||||
template<class T>
|
||||
constexpr bool has_single_bit(T x) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr T bit_ceil(T x) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr T bit_floor(T x) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr int bit_width(T x) noexcept;
|
||||
|
||||
// Rotating
|
||||
|
||||
template<class T>
|
||||
constexpr T rotl(T x, int s) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr T rotr(T x, int s) noexcept;
|
||||
|
||||
// Counting
|
||||
|
||||
template<class T>
|
||||
constexpr int countl_zero(T x) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr int countl_one(T x) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr int countr_zero(T x) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr int countr_one(T x) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr int popcount(T x) noexcept;
|
||||
|
||||
// Endian
|
||||
|
||||
enum class endian
|
||||
{
|
||||
little = see below,
|
||||
big = see below,
|
||||
native = see below
|
||||
};
|
||||
|
||||
using endian_type = endian; // portable alias for C++03 code
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
Note: even though the functions are shown as `constexpr` in the synopsis, since they are implemented
|
||||
via compiler-specific intrinsics, portable code cannot generally rely on their being usable in a
|
||||
constant expression context.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section bit_cast]
|
||||
|
||||
`template<class To, class From> To bit_cast(From const& from) noexcept;`
|
||||
|
||||
* *Requires:* `To` and `From` must be trivially copyable and `sizeof(To)` must be the same as `sizeof(From)`.
|
||||
* *Returns:* A value of type `To` with the storage bytes copied from `from`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section byteswap]
|
||||
|
||||
`template<class T> constexpr T byteswap(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an integer type (i.e. one of `char`, `signed char`,
|
||||
`unsigned char`, `short`, `unsigned short`, `int`, `unsigned int`, `long`,
|
||||
`unsigned long`, `long long`, `unsigned long long`) without padding bits.
|
||||
* *Returns:* `x` with the storage bytes reversed.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Integral powers of 2]
|
||||
|
||||
`template<class T> constexpr bool has_single_bit(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type (i.e. one of `unsigned char`, `unsigned short`, `unsigned int`, `unsigned long`, `unsigned long long`).
|
||||
* *Returns:* `true` if `x` is an integral power of two, `false` otherwise. (`has_single_bit(0u)` is false.)
|
||||
|
||||
`template<class T> constexpr T bit_ceil(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* The smallest integral power of 2 greater than or equal to `x`. If this value is not representable in `T`, behavior is undefined.
|
||||
|
||||
`template<class T> constexpr T bit_floor(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* If `x == 0`, 0; otherwise the maximal value `y` such that `has_single_bit(y)` is `true` and `y <= x`.
|
||||
|
||||
`template<class T> constexpr int bit_width(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* If `x == 0`, 0; otherwise one plus the base-2 logarithm of `x`, with any fractional part discarded.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Rotating]
|
||||
|
||||
In the following descriptions, `N` denotes `numeric_limits<T>::digits` and `r` denotes `s % N`.
|
||||
|
||||
`template<class T> constexpr T rotl(T x, int s) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* If `s` is negative, `rotr(x, -s)`; if `r` is 0, `x`; if `r` is positive, `(x << r) | (x >> (N - r))`.
|
||||
|
||||
`template<class T> constexpr T rotr(T x, int s) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* If `s` is negative, `rotl(x, -s)`; if `r` is 0, `x`; if `r` is positive, `(x >> r) | (x << (N - r))`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Counting]
|
||||
|
||||
`template<class T> constexpr int countl_zero(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* The number of consecutive 0 bits in the value of `x`, starting from the most significant ("left") bit.
|
||||
|
||||
`template<class T> constexpr int countl_one(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* The number of consecutive 1 bits in the value of `x`, starting from the most significant bit.
|
||||
|
||||
`template<class T> constexpr int countr_zero(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* The number of consecutive 0 bits in the value of `x`, starting from the least significant ("right") bit.
|
||||
|
||||
`template<class T> constexpr int countr_one(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* The number of consecutive 1 bits in the value of `x`, starting from the least significant bit.
|
||||
|
||||
`template<class T> constexpr int popcount(T x) noexcept;`
|
||||
|
||||
* *Requires:* `T` must be an unsigned integer type.
|
||||
* *Returns:* The number of 1 bits in the value of `x`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Endian]
|
||||
|
||||
Under C++11, `endian` is defined as `enum class endian` as shown in the synopsis. Under C++03, its definition is
|
||||
|
||||
``
|
||||
namespace endian
|
||||
{
|
||||
enum type
|
||||
{
|
||||
little = see below,
|
||||
big = see below,
|
||||
native = see below
|
||||
};
|
||||
}
|
||||
|
||||
typedef endian::type endian_type;
|
||||
``
|
||||
|
||||
The values of `endian::big` and `endian::little` are distinct. `endian::native` is equal to `endian::big` on
|
||||
big endian platforms, equal to `endian::little` on little endian platforms, and a distinct value on platforms
|
||||
that are neither.
|
||||
|
||||
Note that you should not rely on `little` and `big` having any specific values, because the C++20 standard
|
||||
leaves these unspecified.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
214
doc/changes.qbk
Normal file
214
doc/changes.qbk
Normal file
@ -0,0 +1,214 @@
|
||||
[/
|
||||
Copyright 2021 Peter Dimov
|
||||
Copyright 2022-2024 Andrey Semashev
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section Revision History]
|
||||
|
||||
[section Changes in 1.86.0]
|
||||
|
||||
* Added a [link core.pointer_in_range `boost/core/pointer_in_range.hpp`] header with a `pointer_in_range`
|
||||
function template to check if a pointer is within a given range.
|
||||
* Fixed `type_name` for abstract classes. ([github_issue 172])
|
||||
* Fixed `boost/core/type_name.hpp` compilation error with MSVC with disabled native `wchar_t` type.
|
||||
([github_issue 173])
|
||||
* Added a workaround for an MSVC [@https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025 bug]
|
||||
causing `empty_value` compilation errors when it is used with a nested class. ([github_pr 175])
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.85.0]
|
||||
|
||||
* Added a new [link core.functor `boost/core/functor.hpp`] header with a `functor` class template
|
||||
for wrapping a raw function into a function object class.
|
||||
* Changed [link core.null_deleter `null_deleter`], [link core.fclose_deleter `fclose_deleter`]
|
||||
and [link core.checked_delete checked deleter] definitions so that they don't bring namespace `boost`
|
||||
into argument-dependent lookup in cases like this:
|
||||
```
|
||||
std::unique_ptr< std::FILE, boost::fclose_deleter > p1, p2;
|
||||
swap(p1, p2); // no longer looks for boost::swap as part of ADL
|
||||
```
|
||||
Users may need to either explicitly qualify the namespace of the called function or add a
|
||||
`using`-declaration.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.84.0]
|
||||
|
||||
* `boost::swap` utility function has been renamed to `boost::core::invoke_swap` to
|
||||
avoid forming a potential infinite recursion when the arguments are not swappable.
|
||||
The new function is defined in `boost/core/invoke_swap.hpp` and is functionally equivalent
|
||||
to `boost::swap`. The old `boost::swap` name is preserved for backward compatibility
|
||||
but deprecated and will be removed in a future release. Its `noexcept` specification
|
||||
has been removed to avoid compile errors caused by compile-time recursion.
|
||||
`BOOST_ALLOW_DEPRECATED_SYMBOLS` or `BOOST_ALLOW_DEPRECATED` can be defined to suppress
|
||||
deprecation warnings for the transition period. ([@https://github.com/boostorg/core/issues/148 #148])
|
||||
* Headers `boost/swap.hpp`, `boost/utility/swap.hpp` and `boost/core/swap.hpp` are
|
||||
deprecated and will be removed. Please, switch to `boost/core/invoke_swap.hpp`.
|
||||
`BOOST_ALLOW_DEPRECATED_HEADERS` or `BOOST_ALLOW_DEPRECATED` can be defined to suppress
|
||||
deprecation warnings.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.83.0]
|
||||
|
||||
* Added support for incomplete types to [link core.type_name `boost::core::type_name`].
|
||||
* Bit manipulation functions in [link core.bit `boost/core/bit.hpp`] are now
|
||||
`constexpr` on recent MSVC versions (VS2019 update 5 and later.)
|
||||
* Added `boost::core::byteswap` (an implementation of `std::byteswap` from
|
||||
C++23) to [link core.bit `boost/core/bit.hpp`].
|
||||
* Moved the yield primitives `sp_thread_pause`, `sp_thread_yield`, `sp_thread_sleep`
|
||||
from SmartPtr implementation details to `boost/core/yield_primitives.hpp`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.82.0]
|
||||
|
||||
* Added [link core.snprintf `boost/core/snprintf.hpp`] header with portable definitions of `snprintf`, `vsnprintf` and
|
||||
their `wchar_t` counterparts.
|
||||
* Deprecated `boost/core/is_same.hpp` and `boost::core::is_same`. The header will be removed in a future release.
|
||||
Users are advised to use [@http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/index.html Boost.TypeTraits]
|
||||
or C++ standard library type traits instead.
|
||||
* Marked `boost::ref` member functions and associated methods with `noexcept`.
|
||||
* Marked `boost::swap` function with `noexcept`, depending on whether the type supports a non-throwing swap operation.
|
||||
* Added [link core.launder `boost::core::launder`], a portable implementation of `std::launder`.
|
||||
* Added [link core.alignof `BOOST_CORE_ALIGNOF`], a portable implementation of `alignof`.
|
||||
* Added [link core.max_align `boost::core::max_align_t`], a portable equivalent of `std::max_align_t`, and
|
||||
`boost::core::max_align`, the alignment of `max_align_t`.
|
||||
* Added [link core.memory_resource `boost::core::memory_resource`], a portable equivalent of `std::pmr::memory_resource`
|
||||
from C++17.
|
||||
* Added [link core.serialization `boost/core/serialization.hpp`], a collection of primitives allowing libraries to
|
||||
implement Boost.Serialization support for their types without including a Serialization header and thereby making
|
||||
their libraries depend on Serialization.
|
||||
* Added [link core.data `boost::data`], an implementation of `std::data`.
|
||||
* Added [link core.size `boost::size`], an implementation of `std::size`.
|
||||
* Updated `boost::span` to use `boost::data` which adds support for range
|
||||
construction from an `std::initializer_list`.
|
||||
* Added [link core.identity `boost::identity`], an implementation of
|
||||
`std::identity`. This facility has been moved from Boost.Functional.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.81.0]
|
||||
|
||||
* [link core.empty_value `empty_value`] members are now marked as `constexpr`.
|
||||
* Added [link core.fclose_deleter `fclose_deleter`], a deleter that calls `std::fclose` on a pointer to `std::FILE`.
|
||||
* Bit manipulation utilities in [link core.bit `boost/core/bit.hpp`] now explicitly require unsigned integers on input.
|
||||
([@https://github.com/boostorg/core/issues/129 #129])
|
||||
* `bit_width` now returns `int` instead of a value of the input argument type. This follows the
|
||||
resolution of [@https://cplusplus.github.io/LWG/issue3656 LWG3656].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.80.0]
|
||||
|
||||
* In [link core.allocator_access `boost/core/allocator_access.hpp`], added detection of `construct` and `destroy`
|
||||
members of an allocator.
|
||||
* `boost/core/alloc_construct.hpp` header is now deprecated and will be removed in a future release. Its functionality
|
||||
was moved to [link core.allocator_access `boost/core/allocator_access.hpp`]. In particular, new methods
|
||||
`allocator_construct_n` and `allocator_destroy_n` were added for allocating and destroying arrays.
|
||||
* Worked around MSVC bug that failed to compile [link core.span `span`] in C++17 mode when Boost.Range headers were included.
|
||||
([@https://github.com/boostorg/core/issues/105 #105], [@https://github.com/boostorg/core/pull/115 PR#115])
|
||||
* Added support for 128-bit integer types in [link core.type_name `type_name`].
|
||||
* In [link core.pointer_traits `pointer_traits`], pointer rebinding now supports C++03 compilers.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.79.0]
|
||||
|
||||
* Added `boost::allocator_traits`, an implementation of `std::allocator_traits`.
|
||||
* Made `boost::pointer_traits` SFINAE friendly.
|
||||
* `boost/iterator.hpp` is deprecated and will be removed in a future release. The header defines the
|
||||
`boost::iterator` template, which is equivalent to `std::iterator` in the `<iterator>` header. However,
|
||||
since `std::iterator` is itself deprecated in C++17, users are advised to remove the use of `boost::iterator`
|
||||
or `std::iterator` from their code.
|
||||
* Added `boost::core::verbose_terminate_handler`, a utility function intended
|
||||
to be passed to `std::set_terminate` that prints information about the
|
||||
uncaught exception to `stderr`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.78.0]
|
||||
|
||||
* Added a generic implementation to `boost/core/cmath.hpp`, enabled when `BOOST_CORE_USE_GENERIC_CMATH`
|
||||
is defined or when the platform does not provide the necessary facilities in `<cmath>`.
|
||||
* Added `boost::core::type_name`, a utility function that returns the name of a type as a string.
|
||||
* Added `boost::span`, a C++11 implementation of C++20's `std::span`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.77.0]
|
||||
|
||||
* `boost/core/uncaught_exceptions.hpp` has been modified for compatibility with Mac OS 10.4 and older.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.76.0]
|
||||
|
||||
* Added implicit conversion between compatible reference wrappers.
|
||||
* Added `boost/core/cmath.hpp`, a portable implementation of the floating point classification functions from `<cmath>`.
|
||||
* Added `boost/core/bit.hpp`, a portable implementation of the C++20 standard header `<bit>`.
|
||||
* Fixed `BOOST_TEST_EQ`, `BOOST_TEST_NE` for character types under C++20.
|
||||
* Revised allocator access utilities (now support VS2013, and no workarounds use `allocator_traits`.)
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.74.0]
|
||||
|
||||
* Implemented the allocator access utilities which provide a replacement for `allocator_traits`
|
||||
with individual traits and functions for each facility. They support the C++11 allocator model
|
||||
when possible and provide a fallback for C++98 compatibility.
|
||||
* Added `BOOST_TEST_WITH` to Lightweight Test.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.71.0]
|
||||
|
||||
* Added functions `alloc_construct`, `alloc_construct_n`, `alloc_destroy`, and `alloc_destroy_n`
|
||||
in `<boost/core/alloc_construct.hpp>` for allocator aware and exception safe construction and
|
||||
destruction of objects and arrays.
|
||||
* Added constexpr functions `first_scalar` in `<boost/core/first_scalar.hpp>` for obtaining a pointer
|
||||
to the first scalar element of an array. Given a pointer of type `T*` they return a pointer of type
|
||||
`remove_all_extents_t<T>*`.
|
||||
* Added class template `noinit_adaptor` in `<boost/core/noinit_adaptor.hpp>` which is an allocator adaptor
|
||||
that converts any allocator into one whose `construct(ptr)` performs default initialization via placement
|
||||
`new`, and whose `destroy(ptr)` invokes the `value_type` destructor directly.
|
||||
* Added class template `default_allocator` in `<boost/core/default_allocator.hpp>`, which can serve as a minimal
|
||||
default allocator that has interface similar to C++20 `std::allocator`, supports configurations with disabled
|
||||
exceptions and does not have `std` as an associated namespace. The allocator uses `operator new` and
|
||||
`operator delete` for allocation.
|
||||
* In `<boost/core/uncaught_exceptions.hpp>` header, added workarounds for better compatibility with QNX SDP 7.0
|
||||
when libc++/libc++abi libraries are used.
|
||||
* The `<boost/detail/sp_typeinfo.hpp>` header is now marked as deprecated and will be removed in a future release.
|
||||
`<boost/core/typeinfo.hpp>` should be used instead.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.69.0]
|
||||
|
||||
* Implemented `boost::empty_value`, for library authors to conveniently leverage the Empty Base Optimization to
|
||||
store objects of potentially empty types.
|
||||
* Implemented `boost::quick_exit` to provide the C++11 standard library facility `std::quick_exit` functionality.
|
||||
* Reduced the number of statics in Lightweight Test, and employ lighter abort behavior for MSVC compilers upon
|
||||
failure to call `boost::report_errors`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.67.0]
|
||||
|
||||
* Updated `to_address` and `pointer_traits` to reflect the design adopted for C++20 in
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r2.html P0653R2].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes in 1.65.0]
|
||||
|
||||
* Implemented `pointer_traits` for C++03 and higher, that implements
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r0.html P0653r0].
|
||||
* Added `BOOST_TEST_GT` and `BOOST_TEST_GE` to Lightweight Test.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
122
doc/cmath.qbk
Normal file
122
doc/cmath.qbk
Normal file
@ -0,0 +1,122 @@
|
||||
[/
|
||||
Copyright 2018 Peter Dimov
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
See accompanying file LICENSE_1_0.txt
|
||||
or copy at http://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:cmath cmath]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/cmath.hpp>]
|
||||
|
||||
The header `<boost/core/cmath.hpp>` defines, in a portable way, the floating
|
||||
point classification and sign manipulation functions from C++11.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
// fpclassify return values
|
||||
|
||||
int const fp_zero = /*unspecified*/;
|
||||
int const fp_subnormal = /*unspecified*/;
|
||||
int const fp_normal = /*unspecified*/;
|
||||
int const fp_infinite = /*unspecified*/;
|
||||
int const fp_nan = /*unspecified*/;
|
||||
|
||||
// Classification functions
|
||||
|
||||
template<class T> bool isfinite( T x );
|
||||
template<class T> bool isnan( T x );
|
||||
template<class T> bool isinf( T x );
|
||||
template<class T> bool isnormal( T x );
|
||||
template<class T> int fpclassify( T x );
|
||||
|
||||
// Sign manipulation functions
|
||||
|
||||
template<class T> bool signbit( T x );
|
||||
template<class T> T copysign( T x, T y );
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Classification Functions]
|
||||
|
||||
[section template<class T> bool isfinite( T x );]
|
||||
|
||||
* *Requires:* `T` must be `float`, `double`, or `long double`.
|
||||
* *Returns:* `true` when `x` is finite (not infinity or NaN), `false` otherwise.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template<class T> bool isnan( T x );]
|
||||
|
||||
* *Requires:* `T` must be `float`, `double`, or `long double`.
|
||||
* *Returns:* `true` when `x` is NaN, `false` otherwise.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template<class T> bool isinf( T x );]
|
||||
|
||||
* *Requires:* `T` must be `float`, `double`, or `long double`.
|
||||
* *Returns:* `true` when `x` is infinity, `false` otherwise.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template<class T> bool isnormal( T x );]
|
||||
|
||||
* *Requires:* `T` must be `float`, `double`, or `long double`.
|
||||
* *Returns:* `true` when `x` is a normal number (not zero, subnormal, infinity, or NaN), `false` otherwise.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template<class T> int fpclassify( T x );]
|
||||
|
||||
* *Requires:* `T` must be `float`, `double`, or `long double`.
|
||||
* *Returns:*
|
||||
* `fp_zero` when `x` is zero;
|
||||
* `fp_subnormal` when `x` is subnormal;
|
||||
* `fp_infinite` when `x` is infinity;
|
||||
* `fp_nan` when `x` is NaN;
|
||||
* `fp_normal` otherwise.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Sign Manipulation Functions]
|
||||
|
||||
[section template<class T> bool signbit( T x );]
|
||||
|
||||
* *Requires:* `T` must be `float`, `double`, or `long double`.
|
||||
* *Returns:* `true` when `x` is negative, `false` otherwise.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template<class T> bool copysign( T x, T y );]
|
||||
|
||||
* *Requires:* `T` must be `float`, `double`, or `long double`.
|
||||
* *Returns:* `x` with the sign copied from `y`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
29
doc/core.qbk
29
doc/core.qbk
@ -20,6 +20,9 @@ or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
]
|
||||
|
||||
[template github_issue[key]'''<ulink url="https://github.com/boostorg/core/issues/'''[key]'''">#'''[key]'''</ulink>''']
|
||||
[template github_pr[key]'''<ulink url="https://github.com/boostorg/core/pull/'''[key]'''">PR#'''[key]'''</ulink>''']
|
||||
|
||||
[template simplesect[title]
|
||||
[block '''<simplesect><title>'''[title]'''</title>''']]
|
||||
|
||||
@ -34,13 +37,20 @@ criteria for inclusion is that the utility component be:
|
||||
* simple,
|
||||
* used by other Boost libraries, and
|
||||
* not dependent on any other Boost modules except Core
|
||||
itself, Config, Assert, Static Assert, or Predef.
|
||||
itself, Config, Assert, StaticAssert, or ThrowException.
|
||||
|
||||
[endsect]
|
||||
|
||||
[include changes.qbk]
|
||||
|
||||
[include addressof.qbk]
|
||||
[include alloc_construct.qbk]
|
||||
[include alignof.qbk]
|
||||
[include allocator_access.qbk]
|
||||
[include allocator_traits.qbk]
|
||||
[include bit.qbk]
|
||||
[include checked_delete.qbk]
|
||||
[include cmath.qbk]
|
||||
[include data.qbk]
|
||||
[include default_allocator.qbk]
|
||||
[include demangle.qbk]
|
||||
[include empty_value.qbk]
|
||||
@ -48,19 +58,34 @@ criteria for inclusion is that the utility component be:
|
||||
[include exchange.qbk]
|
||||
[include explicit_operator_bool.qbk]
|
||||
[include first_scalar.qbk]
|
||||
[include functor.qbk]
|
||||
[include identity.qbk]
|
||||
[include ignore_unused.qbk]
|
||||
[include is_same.qbk]
|
||||
[include launder.qbk]
|
||||
[include lightweight_test.qbk]
|
||||
[include make_span.qbk]
|
||||
[include max_align.qbk]
|
||||
[include memory_resource.qbk]
|
||||
[include no_exceptions_support.qbk]
|
||||
[include noinit_adaptor.qbk]
|
||||
[include noncopyable.qbk]
|
||||
[include null_deleter.qbk]
|
||||
[include fclose_deleter.qbk]
|
||||
[include nvp.qbk]
|
||||
[include pointer_in_range.qbk]
|
||||
[include pointer_traits.qbk]
|
||||
[include quick_exit.qbk]
|
||||
[include ref.qbk]
|
||||
[include scoped_enum.qbk]
|
||||
[include serialization.qbk]
|
||||
[include size.qbk]
|
||||
[include span.qbk]
|
||||
[include swap.qbk]
|
||||
[include typeinfo.qbk]
|
||||
[include type_name.qbk]
|
||||
[include snprintf.qbk]
|
||||
[include uncaught_exceptions.qbk]
|
||||
[include use_default.qbk]
|
||||
[include verbose_terminate_handler.qbk]
|
||||
[include yield_primitives.qbk]
|
||||
|
67
doc/data.qbk
Normal file
67
doc/data.qbk
Normal file
@ -0,0 +1,67 @@
|
||||
[/
|
||||
Copyright 2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:data data]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
The header <boost/core/data.hpp> provides function templates `data`
|
||||
to obtain the pointer to the first element in a range.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class C>
|
||||
constexpr auto
|
||||
data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data());
|
||||
|
||||
template<class C>
|
||||
constexpr auto
|
||||
data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data());
|
||||
|
||||
template<class T, std::size_t N>
|
||||
constexpr T*
|
||||
data(T(&a)[N]) noexcept;
|
||||
|
||||
template<class T>
|
||||
constexpr const T*
|
||||
data(std::initializer_list<T> l) noexcept;
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
[section Functions]
|
||||
|
||||
[variablelist
|
||||
[[`template<class C> constexpr auto data(C& c) noexcept(noexcept(c.data())) ->
|
||||
decltype(c.data());`]
|
||||
[Returns `c.data()`.]]
|
||||
[[`template<class C> constexpr auto data(const C& c)
|
||||
noexcept(noexcept(c.data())) -> decltype(c.data());`]
|
||||
[Returns `c.data()`.]]
|
||||
[[`template<class T, std::size_t N> constexpr T* data(T(&a)[N]) noexcept;`]
|
||||
[Returns `a`.]]
|
||||
[[`template<class T> constexpr const T* data(std::initializer_list<T> l)
|
||||
noexcept;`]
|
||||
[Returns `l.begin()`.]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
@ -125,7 +125,7 @@ return `nullptr` if demangling failed.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Acknowledgments]
|
||||
[section Acknowledgements]
|
||||
|
||||
The implementation of `core::demangle` was taken from
|
||||
`boost/exception/detail/type_info.hpp`, which in turn was adapted
|
||||
|
@ -90,13 +90,15 @@ public:
|
||||
empty_value() = default;
|
||||
|
||||
template<class... Args>
|
||||
explicit empty_value(empty_init_t, Args&&... args);
|
||||
constepxr empty_value(empty_init_t, Args&&... args);
|
||||
|
||||
const T& get() const noexcept;
|
||||
constepxr const T& get() const noexcept;
|
||||
|
||||
T& get() noexcept;
|
||||
constepxr T& get() noexcept;
|
||||
};
|
||||
|
||||
inline constexpr empty_init_t empty_init{ };
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
@ -119,8 +121,9 @@ public:
|
||||
[section Constructors]
|
||||
|
||||
[variablelist
|
||||
[[`empty_value() = default;`][Default initialize the value]]
|
||||
[[`template<class... Args> empty_value(empty_init_t, Args&&... args);`]
|
||||
[[`constepxr empty_value() = default;`][Default initialize the value]]
|
||||
[[`template<class... Args>
|
||||
constepxr empty_value(empty_init_t, Args&&... args);`]
|
||||
[Initialize the value with `std::forward<Args>(args)...`]]]
|
||||
|
||||
[endsect]
|
||||
@ -128,8 +131,8 @@ public:
|
||||
[section Member functions]
|
||||
|
||||
[variablelist
|
||||
[[`const T& get() const noexcept;`][Returns the value]]
|
||||
[[`T& get() noexcept;`][Returns the value]]]
|
||||
[[`constepxr const T& get() const noexcept;`][Returns the value]]
|
||||
[[`constepxr T& get() noexcept;`][Returns the value]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -304,8 +304,8 @@ depends on the template arguments of the class. Note that
|
||||
again, the second argument to `enable_if` is not needed; the
|
||||
default (`void`) is the correct value.
|
||||
|
||||
The `enable_if_has_type` template is usable this scenario but instead of
|
||||
using a type traits to enable or disable a specialization, it use a
|
||||
The `enable_if_has_type` template is usable in this scenario but instead of
|
||||
using a type trait to enable or disable a specialization, it uses a
|
||||
SFINAE context to check for the existence of a dependent type inside
|
||||
its parameter. For example, the following structure extracts a dependent
|
||||
`value_type` from T if and only if `T::value_type` exists.
|
||||
|
34
doc/fclose_deleter.qbk
Normal file
34
doc/fclose_deleter.qbk
Normal file
@ -0,0 +1,34 @@
|
||||
[/
|
||||
/ Copyright (c) 2022 Andrey Semashev
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:fclose_deleter fclose_deleter]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Andrey Semashev
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/fclose_deleter.hpp>]
|
||||
|
||||
The header `<boost/core/fclose_deleter.hpp>` defines the `boost::fclose_deleter` function object,
|
||||
which can be used as a deleter with smart pointers such as `unique_ptr` or `shared_ptr` pointing to `std::FILE`.
|
||||
structures returned by `std::fopen` calls. The deleter calls `std::fclose` on the passed pointer, causing
|
||||
the file stream to be flushed and closed.
|
||||
|
||||
[section Example]
|
||||
``
|
||||
std::unique_ptr< std::FILE, boost::fclose_deleter > make_file(const char* filename, const char* open_mode)
|
||||
{
|
||||
return { std::fopen(filename, open_mode) };
|
||||
}
|
||||
``
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
101
doc/functor.qbk
Normal file
101
doc/functor.qbk
Normal file
@ -0,0 +1,101 @@
|
||||
[/
|
||||
/ Copyright (c) 2024 Andrey Semashev
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:functor functor]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Andrey Semashev
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/functor.hpp>]
|
||||
|
||||
[note This component requires a compiler supporting C++17 or newer.]
|
||||
|
||||
The header `<boost/core/functor.hpp>` defines the `boost::core::functor` class template
|
||||
that wraps a raw function specified in its template parameter into a function object class.
|
||||
The function object forwards any arguments passed to it to the wrapped function and returns
|
||||
the result of the call.
|
||||
|
||||
The `functor` wrapper can be useful in cases when a function object class type is required,
|
||||
for example, for use with smart pointers such as `std::unique_ptr`, where the actual logic
|
||||
of the function object is already implemented as a raw function, possibly provided by a
|
||||
third party library. Since `functor` is default-constructible and does not store a pointer
|
||||
to the wrapped function internally, using `functor` is less error-prone and more efficient
|
||||
than using the pointer to function instead. For example, with `std::unique_ptr` you don't
|
||||
need to pass a pointer to the deleter function in the `std::unique_ptr` constructor, and
|
||||
the `std::unique_ptr` object does not store and invoke a pointer to the deleter function.
|
||||
With `functor`, the deleter function becomes part of the `std::unique_ptr` type, which
|
||||
prevents mixing pointers with incompatible deleters.
|
||||
|
||||
```
|
||||
void my_deleter(void* p);
|
||||
|
||||
using malloc_ptr = std::unique_ptr< char, boost::core::functor< std::free > >;
|
||||
using my_ptr = std::unique_ptr< char, boost::core::functor< my_deleter > >;
|
||||
|
||||
my_ptr create_string(std::size_t size);
|
||||
void consume_string(my_ptr&& str);
|
||||
|
||||
malloc_ptr ptr1(static_cast< char* >(std::malloc(size)));
|
||||
// ptr1 = allocate_string(size); // error, cannot convert my_ptr to malloc_ptr
|
||||
my_ptr ptr2 = create_string(size); // ok
|
||||
|
||||
// consume_string(std::move(ptr1)); // error, cannot convert malloc_ptr&& to my_ptr
|
||||
consume_string(std::move(ptr2)); // ok
|
||||
```
|
||||
|
||||
Using `functor` may also be beneficial for reducing generated code sizes. For example, in
|
||||
order to avoid storing and invoking a pointer to the deleter function in `std::shared_ptr`,
|
||||
one may be inclined to use lambda functions to wrap the deleter function call like this:
|
||||
|
||||
```
|
||||
std::shared_ptr< int > ptr(static_cast< int* >(std::malloc(sizeof(int))), [](int* p) { std::free(p); });
|
||||
```
|
||||
|
||||
The problem is that every lambda function declaration introduces a unique type, even if
|
||||
the lambda function definition matches exactly one of the previously declared lambda
|
||||
functions. Thus, if `std::shared_ptr` objects like the one above are created in multiple
|
||||
places in the program, the definition of the shared pointer counter and associated code
|
||||
and data (e.g. virtual function table) will be duplicated for each instance.
|
||||
|
||||
Replacing the lambda function with `functor` solves this problem without sacrificing
|
||||
readability or efficiency:
|
||||
|
||||
```
|
||||
std::shared_ptr< int > ptr(static_cast< int* >(std::malloc(sizeof(int))), boost::core::functor< std::free >());
|
||||
```
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
```
|
||||
namespace boost::core {
|
||||
|
||||
template< auto Function >
|
||||
struct functor
|
||||
{
|
||||
template< typename... Args >
|
||||
decltype(auto) operator() (Args&&... args) const noexcept(...);
|
||||
};
|
||||
|
||||
} // namespace boost::core
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `template< typename... Args > decltype(auto) operator() (Args&&... args) const noexcept(...);`]
|
||||
|
||||
* *Effects:* `return Function(std::forward< Args >(args)...)`.
|
||||
* *Throws:* Nothing, unless invoking `Function` throws.
|
||||
* *Note:* This function only participates in overload resolution if `Function(std::forward< Args >(args)...)` is a valid call expression.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
61
doc/identity.qbk
Normal file
61
doc/identity.qbk
Normal file
@ -0,0 +1,61 @@
|
||||
[/
|
||||
Copyright 2021-2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:identity identity]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
The header <boost/functional/identity.hpp> provides the function object
|
||||
`boost::identity` whose `operator()` returns its argument. It is an
|
||||
implementation of C++20's `std::identity` that supports C++03 and above.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Example]
|
||||
|
||||
It is commonly used as the default projection in constrained algorithms.
|
||||
|
||||
```
|
||||
template<class Range, class Projection = boost::identity>
|
||||
void print(Range&& range, Projection projection = {});
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
struct identity {
|
||||
using is_transparent = unspecified;
|
||||
|
||||
template<class T>
|
||||
T&& operator()(T&& value) const noexcept;
|
||||
};
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
[section Operators]
|
||||
|
||||
[variablelist
|
||||
[[`template<class T> T&& operator()(T&& value) const noexcept;`]
|
||||
[Returns `std::forward<T>(value)`.]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
@ -51,7 +51,7 @@ int fun( int foo, int bar )
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Acknowledgments]
|
||||
[section Acknowledgements]
|
||||
|
||||
`boost::ignore_unused()` was contributed by Adam Wulkiewicz.
|
||||
|
||||
|
@ -17,6 +17,11 @@
|
||||
|
||||
[section Header <boost/core/is_same.hpp>]
|
||||
|
||||
[warning This component is deprecated and will be removed in a future release.
|
||||
Users are recommended to use `boost::is_same` from
|
||||
[@http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/index.html Boost.TypeTraits]
|
||||
or `std::is_same` from C++ standard library `<type_traits>` instead.]
|
||||
|
||||
The header `<boost/core/is_same.hpp>` defines the class template
|
||||
`boost::core::is_same<T1,T2>`. It defines a nested integral constant
|
||||
`value` which is `true` when `T1` and `T2` are the same type, and
|
||||
|
39
doc/launder.qbk
Normal file
39
doc/launder.qbk
Normal file
@ -0,0 +1,39 @@
|
||||
[/
|
||||
Copyright 2023 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:launder launder]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/launder.hpp>]
|
||||
|
||||
The header `<boost/core/launder.hpp>` defines the function
|
||||
`void boost::core::launder()`, a portable implementation of
|
||||
`std::launder`.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
template<class T> T* launder( T* p );
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
@ -43,14 +43,24 @@ When using `lightweight_test.hpp`, *do not forget* to
|
||||
#define BOOST_TEST_GE(expr1, expr2) /*unspecified*/
|
||||
#define BOOST_TEST_CSTR_EQ(expr1, expr2) /*unspecified*/
|
||||
#define BOOST_TEST_CSTR_NE(expr1, expr2) /*unspecified*/
|
||||
#define BOOST_TEST_WITH(expr1, expr2, pred) /*unspecified*/
|
||||
#define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2) /* unspecified */
|
||||
#define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) /* unspecified */
|
||||
#define BOOST_TEST_THROWS(expr, excep) /*unspecified*/
|
||||
#define BOOST_TEST_NO_THROW(expr) /*unspecified*/
|
||||
|
||||
namespace boost
|
||||
{
|
||||
int report_errors();
|
||||
}
|
||||
|
||||
int report_errors();
|
||||
|
||||
namespace core
|
||||
{
|
||||
|
||||
void lwt_init();
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
@ -174,6 +184,17 @@ Specialization of `BOOST_TEST_NE` which interprets `expr1` and `expr2` as pointe
|
||||
|
||||
[endsect]
|
||||
|
||||
[section BOOST_TEST_WITH]
|
||||
|
||||
``
|
||||
BOOST_TEST_WITH(expr1, expr2, pred)
|
||||
``
|
||||
|
||||
If `pred(expr1, expr2)` is not true increases the error count and outputs a
|
||||
message containing both expressions.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section BOOST_TEST_ALL_EQ]
|
||||
|
||||
``
|
||||
@ -209,6 +230,20 @@ nothing and `expr` is not evaluated.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section BOOST_TEST_NO_THROW]
|
||||
|
||||
``
|
||||
BOOST_TEST_NO_THROW(expr)
|
||||
``
|
||||
|
||||
If `BOOST_NO_EXCEPTIONS` is *not* defined and if `expr` throws an exception,
|
||||
increases the error count and outputs a message containing the expression
|
||||
and (if possible) the exception message.
|
||||
|
||||
If `BOOST_NO_EXCEPTIONS` is defined, `expr` is evaluated.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section report_errors]
|
||||
|
||||
``
|
||||
@ -219,6 +254,25 @@ Return the error count from `main`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section lwt_init]
|
||||
|
||||
``
|
||||
void boost::core::lwt_init()
|
||||
``
|
||||
|
||||
Performs one-time initialization. Disables the interactive message
|
||||
boxes displayed by the Microsoft Windows debug runtime library on
|
||||
`abort`, failing `assert`, and other abnormal program terminations
|
||||
(to facilitate unattended testing), and ensures that in case
|
||||
`boost::report_errors` is not called (a common mistake), the program
|
||||
ends with a nonzero exit code.
|
||||
|
||||
`lwt_init` is automatically called by the test macros. There is
|
||||
no need to call it explicitly, except in cases where a test fails due
|
||||
to e.g. an assertion failure before the first test macro is invoked.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Example]
|
||||
|
||||
``
|
||||
@ -299,14 +353,14 @@ parentheses.)
|
||||
|
||||
``
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/core/is_same.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
template<class T, class U> struct X
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
using boost::core::is_same;
|
||||
using boost::is_same;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
81
doc/make_span.qbk
Normal file
81
doc/make_span.qbk
Normal file
@ -0,0 +1,81 @@
|
||||
[/
|
||||
Copyright 2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:make_span make_span]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
The header <boost/core/make_span.hpp> provides function templates `make_span`
|
||||
to conveniently create `span` objects. They are useful before C++17 where Class
|
||||
Template Argument Deduction (CTAD) is not available.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class I>
|
||||
constexpr span<I>
|
||||
make_span(I* d, std::size_t n) noexcept;
|
||||
|
||||
template<class I>
|
||||
constexpr span<I>
|
||||
make_span(I* b, I* e) noexcept;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
constexpr span<T, N>
|
||||
make_span(T(&a)[N]) noexcept;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
constexpr span<T, N>
|
||||
make_span(std::array<T, N>& a) noexcept;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
constexpr span<const T, N>
|
||||
make_span(const std::array<T, N>& a) noexcept;
|
||||
|
||||
template<class R>
|
||||
span<remove_pointer_t<iterator_t<R> > >
|
||||
make_span(R&& r);
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
[section Functions]
|
||||
|
||||
[variablelist
|
||||
[[`template<class I> span<I> make_span(I* f, std::size_t c);`]
|
||||
[Returns `span<I>(f, c)`.]]
|
||||
[[`template<class I> span<I> make_span(I* f, I* l);`]
|
||||
[Returns `span<I>(f, l)`.]]
|
||||
[[`template<class T, std::size_t N> span<T, N> make_span(T(&a)[N]);`]
|
||||
[Returns `span<T, N>(a)`.]]
|
||||
[[`template<class T, std::size_t N> span<T, N>
|
||||
make_span(std::array<T, N>& a);`]
|
||||
[Returns `span<T, N>(a)`.]]
|
||||
[[`template<class T, std::size_t N> span<const T, N>
|
||||
make_span(const std::array<T, N>& a);`]
|
||||
[Returns `span<const T, N>(a)`.]]
|
||||
[[`template<class R>
|
||||
span<remove_pointer_t<iterator_t<R> > >
|
||||
make_span(R&& r);`]
|
||||
[Returns `span<remove_pointer_t<iterator_t<R> > >(std::forward<R>(r))`.]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
42
doc/max_align.qbk
Normal file
42
doc/max_align.qbk
Normal file
@ -0,0 +1,42 @@
|
||||
[/
|
||||
Copyright 2023 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:max_align max_align]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/max_align.hpp>]
|
||||
|
||||
The header `<boost/core/max_align.hpp>` defines the type
|
||||
`boost::core::max_align_t`, a portable equivalent of
|
||||
`std::max_align_t`, and the constant `boost::core::max_align`,
|
||||
the alignment of `max_align_t`.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
union max_align_t;
|
||||
|
||||
constexpr std::size_t max_align = alignof(max_align_t);
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
139
doc/memory_resource.qbk
Normal file
139
doc/memory_resource.qbk
Normal file
@ -0,0 +1,139 @@
|
||||
[/
|
||||
Copyright 2023 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:memory_resource memory_resource]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/memory_resource.hpp>]
|
||||
|
||||
The header `<boost/core/memory_resource.hpp>` defines the class
|
||||
`boost::core::memory_resource`, a portable equivalent of
|
||||
`std::pmr::memory_resource` from C++17.
|
||||
|
||||
This is not a complete implementation of the standard `<memory_resource>`
|
||||
header; for such, one should use Boost.Container. The abstract base class
|
||||
is only provided by Core so that Boost libraries that provide and take
|
||||
advantage of PMR facilities such as concrete implementations of memory
|
||||
resources, or implementations of `polymorphic_allocator`, can interoperate.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
class memory_resource
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~memory_resource() = default;
|
||||
|
||||
[[nodiscard]] void* allocate( std::size_t bytes, std::size_t alignment = max_align );
|
||||
void deallocate( void* p, std::size_t bytes, std::size_t alignment = max_align );
|
||||
|
||||
bool is_equal( memory_resource const & other ) const noexcept;
|
||||
|
||||
private:
|
||||
|
||||
virtual void* do_allocate( std::size_t bytes, std::size_t alignment ) = 0;
|
||||
virtual void do_deallocate( void* p, std::size_t bytes, std::size_t alignment ) = 0;
|
||||
|
||||
virtual bool do_is_equal( memory_resource const& other ) const noexcept = 0;
|
||||
};
|
||||
|
||||
inline bool operator==( memory_resource const& a, memory_resource const& b ) noexcept;
|
||||
inline bool operator!=( memory_resource const& a, memory_resource const& b ) noexcept;
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `allocate`]
|
||||
|
||||
`[[nodiscard]] void* allocate( std::size_t bytes, std::size_t alignment = max_align );`
|
||||
|
||||
* *Returns:* `do_allocate( bytes, alignment )`.
|
||||
* *Remarks:* Implicitly creates objects in the returned region of storage.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `deallocate`]
|
||||
|
||||
`void deallocate( void* p, std::size_t bytes, std::size_t alignment = max_align );`
|
||||
|
||||
* *Effects:* `do_deallocate( bytes, alignment )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `is_equal`]
|
||||
|
||||
`bool is_equal( memory_resource const& other ) const noexcept;`
|
||||
|
||||
* *Returns:* `do_is_equal( other )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `do_allocate`]
|
||||
|
||||
`void* do_allocate( std::size_t bytes, std::size_t alignment ) = 0;`
|
||||
|
||||
* *Remarks:* A derived class should implement this member function to return
|
||||
a pointer to allocated storage of size at least `bytes` and alignment at
|
||||
least `alignment`.
|
||||
* *Throws:* An appropriate exception (by convention `std::bad_alloc` or
|
||||
derived) when storage with the specified size and alignment could not be
|
||||
obtained.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `do_deallocate`]
|
||||
|
||||
`void do_deallocate( void* p, std::size_t bytes, std::size_t alignment ) = 0;`
|
||||
|
||||
* *Remarks:* A derived class should implement this member function to deallocate
|
||||
a region of storage previously allocated by `do_allocate`.
|
||||
* *Throws:* Nothing.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `do_is_equal`]
|
||||
|
||||
`bool do_is_equal( memory_resource const& other ) const noexcept = 0;`
|
||||
|
||||
* *Remarks:* A derived class shall implement this function to return `true` if
|
||||
memory allocated from `*this` can be deallocated from `other` and vice-versa,
|
||||
otherwise `false`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `operator==`]
|
||||
|
||||
`bool operator==( memory_resource const& a, memory_resource const& b ) noexcept;`
|
||||
|
||||
* *Returns:* `&a == &b || a.is_equal( b )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `operator!=`]
|
||||
|
||||
`bool operator!=( memory_resource const& a, memory_resource const& b ) noexcept;`
|
||||
|
||||
* *Returns:* `!( a == b )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
@ -71,8 +71,7 @@ struct noinit_adaptor
|
||||
: A {
|
||||
template<class U>
|
||||
struct rebind {
|
||||
typedef noinit_adaptor<typename std::allocator_traits<A>::template
|
||||
rebind_alloc<U> > other;
|
||||
typedef noinit_adaptor<allocator_rebind_t<A, U> > other;
|
||||
};
|
||||
|
||||
noinit_adaptor() noexcept;
|
||||
@ -86,9 +85,6 @@ struct noinit_adaptor
|
||||
template<class U>
|
||||
void construct(U* p);
|
||||
|
||||
template<class U, class V, class... Args>
|
||||
void construct(U* p, V&& v, Args&&... args);
|
||||
|
||||
template<class U>
|
||||
void destroy(U* p);
|
||||
};
|
||||
@ -121,7 +117,7 @@ noinit_adaptor<A> noinit_adapt(const A& a) noexcept;
|
||||
[[variablelist
|
||||
[[Requires][`A` shall be constructible from `U`.]]
|
||||
[[Effects][Initializes the `A` base class with
|
||||
`static_cast<const U&>(u)`.]]]]]]
|
||||
`static_cast<const A&>(u)`.]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
@ -131,11 +127,6 @@ noinit_adaptor<A> noinit_adapt(const A& a) noexcept;
|
||||
[[`template<class U> void construct(U* p);`]
|
||||
[[variablelist
|
||||
[[Effects][`::new((void*)p) U`.]]]]]
|
||||
[[`template<class U, class V, class... Args> void construct(U* p, V&& v,
|
||||
Args&&... args);`]
|
||||
[[variablelist
|
||||
[[Effects][`::new(void*)p) U(std::forward<V>(v),
|
||||
std::forward<Args>(args)...)`.]]]]]
|
||||
[[`template<class U> void destroy(U* p);`]
|
||||
[[variablelist
|
||||
[[Effects][`p->~U()`.]]]]]]
|
||||
|
81
doc/pointer_in_range.qbk
Normal file
81
doc/pointer_in_range.qbk
Normal file
@ -0,0 +1,81 @@
|
||||
[/
|
||||
Copyright 2024 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:pointer_in_range pointer_in_range]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
The header <boost/core/pointer_in_range.hpp> provides the function template
|
||||
`boost::pointer_in_range` to check if a pointer is in a given range. This
|
||||
can be used in constant expressions in C++14 or higher when the compiler has a
|
||||
builtin to support `std::is_constant_evaluated`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
|
||||
The following is an example of an allocator's deallocation function that does
|
||||
nothing if the pointer falls within a small automatically allocated buffer.
|
||||
|
||||
```
|
||||
template<class T, class N>
|
||||
void
|
||||
Allocator<T, N>::deallocate(pointer ptr, size_type)
|
||||
{
|
||||
if (!boost::pointer_in_range(ptr, buffer_, buffer_ + N)) {
|
||||
::operator delete(ptr);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
constexpr bool pointer_in_range(const T* ptr, const T* begin, const T* end);
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
[section Functions]
|
||||
|
||||
[variablelist
|
||||
[[`template<class T> constexpr bool pointer_in_range(const T* ptr,
|
||||
const T* begin, const T* end);`]
|
||||
[[variablelist
|
||||
[[Requires][`[begin,end)` is a valid range.]]
|
||||
[[Returns][`true` if `ptr` is in range `[begin,end)`, otherwise `false`.]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Notes]
|
||||
|
||||
If `boost::pointer_in_range` is not usable in constant expressions the macro
|
||||
`BOOST_CORE_NO_CONSTEXPR_POINTER_IN_RANGE` is defined.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section History]
|
||||
|
||||
Glen Fernandes implemented `pointer_in_range`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
@ -1,5 +1,5 @@
|
||||
[/
|
||||
Copyright 2017-2018 Glen Joseph Fernandes
|
||||
Copyright 2017-2021 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
@ -47,68 +47,91 @@ void function(Allocator& a)
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
template<class T> struct pointer_traits {
|
||||
|
||||
template<class T>
|
||||
struct pointer_traits {
|
||||
typedef T pointer;
|
||||
typedef ``['see below]`` element_type;
|
||||
typedef ``['see below]`` difference_type;
|
||||
|
||||
template<class U> struct rebind_to { typedef ``['see below]`` type; };
|
||||
template<class U> using rebind = typename rebind_to<U>::type;
|
||||
template<class U>
|
||||
struct rebind_to {
|
||||
typedef ``['see below]`` type;
|
||||
};
|
||||
|
||||
static pointer pointer_to(``['see below]`` v);
|
||||
};
|
||||
template<class U>
|
||||
using rebind = typename rebind_to<U>::type;
|
||||
|
||||
template<class T> struct pointer_traits<T*> {
|
||||
static pointer pointer_to(element_type& v);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct pointer_traits<T*> {
|
||||
typedef T* pointer;
|
||||
typedef T element_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template<class U> struct rebind_to { typedef U* type; };
|
||||
template<class U> using rebind = typename rebind_to<U>::type;
|
||||
template<class U>
|
||||
struct rebind_to {
|
||||
typedef U* type;
|
||||
};
|
||||
|
||||
template<class U>
|
||||
using rebind = typename rebind_to<U>::type;
|
||||
|
||||
static pointer pointer_to(``['see below]`` v) noexcept;
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
constexpr T* to_address(T* v) noexcept;
|
||||
template<class T>
|
||||
constexpr T* to_address(T* v) noexcept;
|
||||
|
||||
template<class T>
|
||||
auto to_address(const T& v) noexcept;
|
||||
}
|
||||
template<class T>
|
||||
auto to_address(const T& v) noexcept;
|
||||
|
||||
} // boost
|
||||
```
|
||||
|
||||
[section Overview]
|
||||
|
||||
If the member type `element_type` is not defined, then all other members are
|
||||
also not defined (`pointer_traits` is SFINAE-friendly).
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Member types]
|
||||
|
||||
[variablelist
|
||||
[[`typedef` ['see below] `element_type;`]
|
||||
[`T::element_type` if such a type exists; otherwise `U` if `T` is a class
|
||||
template instantiation of the form `Pointer<U, Args>`, where `Args` is zero
|
||||
or more type arguments; otherwise the specialization is ill-formed.]]
|
||||
or more type arguments; otherwise the member is not defined.]]
|
||||
[[`typedef` ['see below] `difference_type;`]
|
||||
[`T::difference_type` if such a type exists; otherwise `std::ptrdiff_t`.]]
|
||||
[[`template<class U> struct rebind_to { typedef` ['see below] `type; };`]
|
||||
[`type` is `T::rebind<U>` if such a type exists; otherwise, `Pointer<V, Args>`
|
||||
if `T` is a class template instantiation of the form `Pointer<T, Args>`,
|
||||
where `Args` is zero or more type arguments; otherwise, the instantiation of
|
||||
`rebind_to` is ill-formed.]]]
|
||||
where `Args` is zero or more type arguments; otherwise, the member is not
|
||||
defined.]]]
|
||||
|
||||
[note When C++11 template aliases are not supported, the `type` for `rebind` is
|
||||
`T::rebind<U>::other` if such a type exists.]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Member functions]
|
||||
|
||||
[variablelist
|
||||
[[`static pointer pointer_traits::pointer_to(`['see below] `v);`]
|
||||
[[`static pointer pointer_traits::pointer_to(element_type& v);`]
|
||||
[[variablelist
|
||||
[[Remark]
|
||||
[If `element_type` is a void type, the type of `v` is unspecified; otherwise,
|
||||
it is `element_type&`.]]
|
||||
[If `element_type` is a void type, or if `T::pointer_to(v)` is not well-formed,
|
||||
this member is not defined.]]
|
||||
[[Returns]
|
||||
[A pointer to `v` obtained by calling `T::pointer_to(v)`.]]]]]
|
||||
[[`static pointer pointer_traits<T*>::pointer_to(`['see below] `v) noexcept;`]
|
||||
[[`static pointer pointer_traits<T*>::pointer_to(element_type& v) noexcept;`]
|
||||
[[variablelist
|
||||
[[Remark]
|
||||
[If `element_type` is a void type, the type of `v` is unspecified; otherwise,
|
||||
it is `element_type&`.]]
|
||||
[If `element_type` is a void type, this member is not defined.]]
|
||||
[[Returns][`addressof(v)`.]]]]]]
|
||||
|
||||
[endsect]
|
||||
@ -142,7 +165,7 @@ namespace boost {
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Acknowledgments]
|
||||
[section Acknowledgements]
|
||||
|
||||
Glen Fernandes implemented `pointer_traits` and `to_address` with reviews and
|
||||
guidance from Peter Dimov.
|
||||
|
@ -68,7 +68,7 @@ The type-expression `boost::unwrap_reference<T>::type` is
|
||||
|
||||
[xinclude ref_reference.xml]
|
||||
|
||||
[section Acknowledgments]
|
||||
[section Acknowledgements]
|
||||
|
||||
`ref` and `cref` were originally part of the Tuple library by
|
||||
Jaakko J\u00E4rvi. They were "promoted to `boost::` status" by
|
||||
|
@ -46,7 +46,7 @@ The user can portably declare such enumeration as follows:
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
|
||||
|
||||
These macros allows to use `future_errc` in almost all the cases as an scoped enum.
|
||||
These macros allow using `future_errc` in almost all the cases as a scoped enum.
|
||||
|
||||
future_errc ev = future_errc::no_state;
|
||||
|
||||
@ -179,7 +179,7 @@ such cases.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Acknowledgments]
|
||||
[section Acknowledgements]
|
||||
|
||||
This scoped enum emulation was developed by Beman Dawes, Vicente J. Botet Escriba and Anthony Williams.
|
||||
|
||||
|
145
doc/serialization.qbk
Normal file
145
doc/serialization.qbk
Normal file
@ -0,0 +1,145 @@
|
||||
[/
|
||||
Copyright 2023 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:serialization serialization]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/serialization.hpp>]
|
||||
|
||||
The header `<boost/core/serialization.hpp>` implements primitives
|
||||
that are necessary to implement Boost.Serialization support without
|
||||
including a Boost.Serialization header and thereby making a library
|
||||
dependent on Boost.Serialization.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
#include <boost/core/nvp.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
|
||||
// forward declarations
|
||||
|
||||
template<class T> struct version;
|
||||
class access;
|
||||
|
||||
// core_version_type
|
||||
|
||||
struct core_version_type;
|
||||
|
||||
} // namespace serialization
|
||||
|
||||
namespace core
|
||||
{
|
||||
|
||||
// nvp
|
||||
|
||||
using serialization::nvp;
|
||||
using serialization::make_nvp;
|
||||
|
||||
// split_free
|
||||
|
||||
template<class Ar, class T> void split_free( Ar& ar, T& t, unsigned int v );
|
||||
|
||||
// split_member
|
||||
|
||||
template<class Ar, class T> void split_member( Ar& ar, T& t, unsigned int v );
|
||||
|
||||
// load_construct_data_adl
|
||||
|
||||
template<class Ar, class T> void load_construct_data_adl( Ar& ar, T* t, unsigned int v );
|
||||
|
||||
// save_construct_data_adl
|
||||
|
||||
template<class Ar, class T> void save_construct_data_adl( Ar& ar, T const* t, unsigned int v );
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `core_version_type`]
|
||||
|
||||
``
|
||||
struct core_version_type
|
||||
{
|
||||
unsigned int version_;
|
||||
|
||||
core_version_type( unsigned int version ): version_( version ) {}
|
||||
operator unsigned int () const { return version_; }
|
||||
};
|
||||
``
|
||||
|
||||
`core_version_type` is a Core reimplementation of
|
||||
`boost::serialization::version_type`, needed to call ADL serialization
|
||||
primitives such as, for example, `load_construct_data` below.
|
||||
|
||||
It's defined in the `serialization` namespace instead of the `core`
|
||||
namespace because its only purpose is to add `boost::serialization` to
|
||||
the list of the associated namespaces of the corresponding call.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `split_free`]
|
||||
|
||||
`template<class Ar, class T> inline void split_free( Ar& ar, T& t, unsigned int v );`
|
||||
|
||||
`boost::core::split_free` is a Core reimplementation of
|
||||
`boost::serialization::split_free`.
|
||||
|
||||
* *Effects:*
|
||||
* If `Ar::is_saving::value` is `true`, calls `save( ar, t, core_version_type( v ) )`;
|
||||
* Otherwise, calls `load( ar, t, core_version_type( v ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `split_member`]
|
||||
|
||||
`template<class Ar, class T> void split_member( Ar& ar, T& t, unsigned int v );`
|
||||
|
||||
`boost::core::split_member` is a Core reimplementation of
|
||||
`boost::serialization::split_member`.
|
||||
|
||||
* *Effects:*
|
||||
* If `Ar::is_saving::value` is `true`, calls `t.save( ar, v )`;
|
||||
* Otherwise, calls `t.load( ar, v )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `load_construct_data_adl`]
|
||||
|
||||
`template<class Ar, class T> void load_construct_data_adl( Ar& ar, T* t, unsigned int v );`
|
||||
|
||||
`boost::core::load_construct_data_adl` is a Core reimplementation of
|
||||
`boost::serialization::load_construct_data_adl`.
|
||||
|
||||
* *Effects:* `load_construct_data( ar, t, serialization::core_version_type( v ) );`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `save_construct_data_adl`]
|
||||
|
||||
`template<class Ar, class T> void save_construct_data_adl( Ar& ar, T const* t, unsigned int v );`
|
||||
|
||||
`boost::core::save_construct_data_adl` is a Core reimplementation of
|
||||
`boost::serialization::save_construct_data_adl`.
|
||||
|
||||
* *Effects:* `save_construct_data( ar, t, serialization::core_version_type( v ) );`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
54
doc/size.qbk
Normal file
54
doc/size.qbk
Normal file
@ -0,0 +1,54 @@
|
||||
[/
|
||||
Copyright 2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:size size]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
The header <boost/core/size.hpp> provides function templates `size` to obtain
|
||||
the number of elements in a range.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class C>
|
||||
constexpr auto
|
||||
size(const C& c) noexcept(noexcept(c.size())) -> decltype(c.size());
|
||||
|
||||
template<class T, std::size_t N>
|
||||
constexpr std::size_t
|
||||
size(T(&)[N]) noexcept;
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
[section Functions]
|
||||
|
||||
[variablelist
|
||||
[[`template<class C> constexpr auto size(const C& c)
|
||||
noexcept(noexcept(c.size())) -> decltype(c.size());`]
|
||||
[Returns `c.size()`.]]
|
||||
[[`template<class T, std::size_t N> constexpr std::size_t size(T(&)[N])
|
||||
noexcept;`]
|
||||
[Returns `N`.]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
47
doc/snprintf.qbk
Normal file
47
doc/snprintf.qbk
Normal file
@ -0,0 +1,47 @@
|
||||
[/
|
||||
/ Copyright (c) 2022 Andrey Semashev
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:snprintf snprintf]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Andrey Semashev
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/snprintf.hpp>]
|
||||
|
||||
The header `<boost/core/snprintf.hpp>` provides portable definition of [@https://en.cppreference.com/w/c/io/fprintf `snprintf`],
|
||||
`vsnprintf` and their corresponding `wchar_t` counterparts. On a platform that supports these functions in the standard library,
|
||||
these definitions are equivalent to the standard functions. On other platforms (mainly, older MSVC versions) these functions
|
||||
are emulated through non-standard functions that have similar behavior.
|
||||
|
||||
Depending on the standard library, certain implementation differences are exposed to the user:
|
||||
|
||||
* Any non-standard behavior with respect to string format description are not hidden by the emulation.
|
||||
* Returned value of `boost::core::snprintf` in case if the output buffer is too small may not be equal to the number of characters
|
||||
that would have been written if the buffer was large enough. It is, however, equal or larger than the buffer size,
|
||||
which still allows the caller to detect the buffer overflow condition. The formatted output is still properly null-terminated
|
||||
in this case.
|
||||
|
||||
[note Unlike `snprintf`, `swprintf` does not return the number of characters to be written if the output buffer is too small
|
||||
but returns -1 instead. Furthermore, `swprintf` may or may not produce characters in the output buffer in this case.]
|
||||
|
||||
[section Example]
|
||||
``
|
||||
char buf[10];
|
||||
int n = boost::core::snprintf(buf, sizeof(buf), "%d", i);
|
||||
if (n < 0)
|
||||
throw std::runtime_error("Formatting error");
|
||||
if (n >= sizeof(buf))
|
||||
throw std::runtime_error("Formatting buffer overflow");
|
||||
``
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
396
doc/span.qbk
Normal file
396
doc/span.qbk
Normal file
@ -0,0 +1,396 @@
|
||||
[/
|
||||
Copyright 2019 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:span span]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Glen Fernandes
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Overview]
|
||||
|
||||
This header <boost/core/span.hpp> provides class template `span`, which is a
|
||||
view over a sequence of objects. It implements the C++20 standard library
|
||||
`std::span` facility. This implementation supports C++11 and higher.
|
||||
|
||||
In addition to referencing the sequence of objects, the span knows the count of
|
||||
objects. There are two kinds of spans:
|
||||
|
||||
* Dynamic size (`span<T>` or `span<T, dynamic_extent>`)
|
||||
* Static size (`span<T, N>`)
|
||||
|
||||
Dynamic size spans have a count that can be a value known at run time. Static
|
||||
size spans have a count that must be known at compile time.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
|
||||
The following snippet shows a function to compute a SHA1 hash whose parameters
|
||||
and return type use spans.
|
||||
|
||||
```
|
||||
auto sha1(boost::span<const unsigned char> input,
|
||||
boost::span<unsigned char, SHA_DIGEST_LENGTH> output)
|
||||
{
|
||||
SHA_CTX context;
|
||||
SHA1_Init(&context);
|
||||
SHA1_Update(&context, input.data(), input.size());
|
||||
SHA1_Final(output.data(), &context);
|
||||
return output;
|
||||
}
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
constexpr std::size_t dynamic_extent = -1;
|
||||
|
||||
template<class T, std::size_t E = dynamic_extent>
|
||||
class span {
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef std::remove_cv_t<T> value_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef std::reverse_iterator<T*> reverse_iterator;
|
||||
typedef std::reverse_iterator<const T*> const_reverse_iterator;
|
||||
|
||||
static constexpr std::size_t extent = E;
|
||||
|
||||
constexpr span() noexcept;
|
||||
|
||||
explicit(E != dynamic_extent)
|
||||
template<class I>
|
||||
constexpr span(I* f, size_type c);
|
||||
|
||||
explicit(E != dynamic_extent)
|
||||
template<class I, class L>
|
||||
constexpr span(I* f, L* l);
|
||||
|
||||
template<std::size_t N>
|
||||
constexpr span(type_identity_t<T> (&a)[N]);
|
||||
|
||||
template<class U, std::size_t N>
|
||||
constexpr span(std::array<U, N>& a) noexcept;
|
||||
|
||||
template<class U, std::size_t N>
|
||||
constexpr span(const std::array<U, N>& a) noexcept;
|
||||
|
||||
explicit(E != dynamic_extent)
|
||||
template<class R>
|
||||
constexpr span(R&& r);
|
||||
|
||||
explicit(E != dynamic_extent && N == dynamic_extent)
|
||||
template<class U, std::size_t N>
|
||||
constexpr span(const span<U, N>& s) noexcept;
|
||||
|
||||
template<std::size_t C>
|
||||
constexpr span<T, C> first() const;
|
||||
|
||||
template<std::size_t C>
|
||||
constexpr span<T, C> last() const;
|
||||
|
||||
template<std::size_t O, std::size_t C = dynamic_extent>
|
||||
constexpr span<T, see below> subspan() const;
|
||||
|
||||
constexpr span<T, dynamic_extent> first(size_type c) const;
|
||||
constexpr span<T, dynamic_extent> last(size_type c) const;
|
||||
|
||||
constexpr span<T, dynamic_extent> subspan(size_type o,
|
||||
size_type c = dynamic_extent) const;
|
||||
|
||||
constexpr size_type size() const noexcept;
|
||||
constexpr size_type size_bytes() const noexcept;
|
||||
constexpr bool empty() const noexcept;
|
||||
|
||||
constexpr reference operator[](size_type i) const;
|
||||
constexpr reference front() const;
|
||||
constexpr reference back() const;
|
||||
constexpr pointer data() const noexcept;
|
||||
|
||||
constexpr iterator begin() const noexcept;
|
||||
constexpr iterator end() const noexcept;
|
||||
constexpr reverse_iterator rbegin() const noexcept;
|
||||
constexpr reverse_iterator rend() const noexcept;
|
||||
constexpr const_iterator cbegin() const noexcept;
|
||||
constexpr const_iterator cend() const noexcept;
|
||||
constexpr const_reverse_iterator crbegin() const noexcept;
|
||||
constexpr const_reverse_iterator crend() const noexcept;
|
||||
};
|
||||
|
||||
template<class I, class L>
|
||||
span(I*, L) -> span<I>;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
span(T(&)[N]) -> span<T, N>;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
span(std::array<T, N>&) -> span<T, N>;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
span(const std::array<T, N>&) -> span<const T, N>;
|
||||
|
||||
template<class R>
|
||||
span(R&&) -> span<remove_pointer_t<iterator_t<R> > >;
|
||||
|
||||
template<class T, std::size_t E>
|
||||
span<const std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
|
||||
as_bytes(span<T, E> s) noexcept;
|
||||
|
||||
template<class T, std::size_t E>
|
||||
span<std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
|
||||
as_writable_bytes(span<T, E> s) noexcept;
|
||||
|
||||
} /* boost */
|
||||
```
|
||||
|
||||
[section Constructors]
|
||||
|
||||
[variablelist
|
||||
[[`constexpr span() noexcept;`]
|
||||
[[variablelist
|
||||
[[Constraints][`E == dynamic_extent || E == 0` is `true`.]]
|
||||
[[Postconditions][`size() == 0 && data() == nullptr`.]]]]]
|
||||
[[`explicit(E != dynamic_extent)
|
||||
template<class I>
|
||||
constexpr span(I* f, size_type c);`]
|
||||
[[variablelist
|
||||
[[Constraints]
|
||||
[`is_convertible_v<I(*)[], T(*)[]>` is `true`.]]
|
||||
[[Preconditions]
|
||||
[[itemized_list
|
||||
[`[f, f + c)` is a valid range.]
|
||||
[If `E` is not equal to `dynamic_extent`, then `c` is equal to `E`.]]]]
|
||||
[[Effects][Constructs a `span` with data `f` and size `c`.]]
|
||||
[[Throws][Nothing.]]]]]
|
||||
[[`explicit(E != dynamic_extent)
|
||||
template<class I, class L>
|
||||
constexpr span(I* f, L* l);`]
|
||||
[[variablelist
|
||||
[[Constraints]
|
||||
[`is_convertible_v<I(*)[], T(*)[]>` is `true`.]]
|
||||
[[Preconditions]
|
||||
[[itemized_list
|
||||
[If `E` is not equal to `dynamic_extent`, then `l - f` is equal to `E`.]
|
||||
[`[f, l)` is a valid range.]]]]
|
||||
[[Effects][Constructs a `span` with data `f` and size `l - f`.]]
|
||||
[[Throws][Nothing.]]]]]
|
||||
[[`template<std::size_t N>
|
||||
constexpr span(type_identity_t<T> (&a)[N]);`]
|
||||
[[variablelist
|
||||
[[Constraints][`E == dynamic_extent || E == N` is `true`.]]
|
||||
[[Effects][Constructs a `span` that is a view over the supplied array.]]
|
||||
[[Postconditions][`size() == N && data() == &a[0]` is `true`.]]]]]
|
||||
[[`template<class U, std::size_t N>
|
||||
constexpr span(std::array<U, N>& a) noexcept;`]
|
||||
[[variablelist
|
||||
[[Constraints]
|
||||
[[itemized_list
|
||||
[`E == dynamic_extent || E == N` is `true`, and]
|
||||
[`U(*)[]` is convertible to `T(*)[]`.]]]]
|
||||
[[Effects][Constructs a `span` that is a view over the supplied array.]]
|
||||
[[Postconditions][`size() == N && data() == a.data()` is `true`.]]]]]
|
||||
[[`template<class U, std::size_t N>
|
||||
constexpr span(const std::array<U, N>& a) noexcept;`]
|
||||
[[variablelist
|
||||
[[Constraints]
|
||||
[[itemized_list
|
||||
[`E == dynamic_extent || E == N` is `true`, and]
|
||||
[`U(*)[]` is convertible to `T(*)[]`.]]]]
|
||||
[[Effects][Constructs a `span` that is a view over the supplied array.]]
|
||||
[[Postconditions][`size() == N && data() == a.data()` is `true`.]]]]]
|
||||
[[`explicit(E != dynamic_extent)
|
||||
template<class R>
|
||||
constexpr span(R&& r);`]
|
||||
[[variablelist
|
||||
[[Constraints]
|
||||
[[itemized_list
|
||||
[`is_lvalue_reference_v<R> || is_const_v<T>` is `true`]
|
||||
[`remove_cvref_t<R>` is not a specialization of `span`,]
|
||||
[`remove_cvref_t<R>` is not a specialization of `array`,]
|
||||
[`is_array_v<remove_cvref_t<R>>` is `false`,]
|
||||
[`data(r)` is well-formed and
|
||||
`is_convertible_v<remove_pointer_t<iterator_t<R> >(*)[],
|
||||
T(*)[]>` is `true`, and]
|
||||
[`r.size()` is well-formed and
|
||||
`is_convertible_v<decltype(declval<R&>().size()), size_t>` is `true`.]]]]
|
||||
[[Effects][Constructs a `span` with data `data(r)` and size `r.size()`.]]
|
||||
[[Throws][What and when data(r) and r.size() throw.]]]]]
|
||||
[[`explicit(E != dynamic_extent && N == dynamic_extent)
|
||||
template<class U, std::size_t N>
|
||||
constexpr span(const span<U, N>& s) noexcept;`]
|
||||
[[variablelist
|
||||
[[Constraints]
|
||||
[[itemized_list
|
||||
[`E == dynamic_extent || N == dynamic_extent || E == N` is `true`, and]
|
||||
[`is_convertible_v<U(*)[], T(*)[]>` is `true`.]]]]
|
||||
[[Preconditions]
|
||||
[If `E` is not equal to `dynamic_extent`, then `s.size()` is equal to `E`.]]
|
||||
[[Effects]
|
||||
[Constructs a `span` that is a view over the range
|
||||
`[s.data(), s.data() + s.size())`.]]
|
||||
[[Postconditions][`size() == s.size() && data() == s.data()`.]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Subviews]
|
||||
|
||||
[variablelist
|
||||
[[`template<std::size_t C> constexpr span<T, C> first() const;`]
|
||||
[[variablelist
|
||||
[[Mandates][`C <= E` is `true`.]]
|
||||
[[Preconditions][`C <= size()` is `true`.]]
|
||||
[[Effects]
|
||||
[Equivalent to `return R{data(), C};` where `R` is the return type.]]]]]
|
||||
[[`template<std::size_t C> constexpr span<T, C> last() const;`]
|
||||
[[variablelist
|
||||
[[Mandates][`C <= E` is `true`.]]
|
||||
[[Preconditions][`C <= size()` is `true`.]]
|
||||
[[Effects]
|
||||
[Equivalent to `return R{data() + (size() - C), C};` where `R` is the return
|
||||
type.]]]]]
|
||||
[[`template<std::size_t O, std::size_t C = dynamic_extent>
|
||||
constexpr span<T, see below> subspan() const;`]
|
||||
[[variablelist
|
||||
[[Mandates][`O <= E && (C == dynamic_extent || C <= E - O)` is `true`.]]
|
||||
[[Preconditions]
|
||||
[`O <= size() && (C == dynamic_extent || C <= size() - O)` is `true`.]]
|
||||
[[Effects]
|
||||
[Equivalent to
|
||||
`return span<T, see below>(data() + O,
|
||||
C != dynamic_extent ? C : size() - O);`.]]
|
||||
[[Remarks]
|
||||
[The second template argument of the returned span type is:
|
||||
`C != dynamic_extent ? C : (E != dynamic_extent ? E - O :
|
||||
dynamic_extent)`]]]]]
|
||||
[[`constexpr span<T, dynamic_extent> first(size_type c) const;`]
|
||||
[[variablelist
|
||||
[[Preconditions][`c <= size()` is `true`.]]
|
||||
[[Effects][Equivalent to: `return {data(), c};`]]]]]
|
||||
[[`constexpr span<T, dynamic_extent> last(size_type c) const;`]
|
||||
[[variablelist
|
||||
[[Preconditions][`c <= size()` is `true`.]]
|
||||
[[Effects][Equivalent to: `return {data() + (size() - c), c};`]]]]]
|
||||
[[`constexpr span<T, dynamic_extent> subspan(size_type o,
|
||||
size_type c = dynamic_extent) const;`]
|
||||
[[variablelist
|
||||
[[Preconditions]
|
||||
[`o <= size() && (c == dynamic_extent || o + c <= size())` is `true`.]]
|
||||
[[Effects]
|
||||
[Equivalent to:
|
||||
`return {data() + o, c == dynamic_extent ? size() - o : c};`]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Observers]
|
||||
|
||||
[variablelist
|
||||
[[`constexpr size_type size() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Returns][The number of elements in the span.]]]]]
|
||||
[[`constexpr size_type size_bytes() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Effects][Equivalent to: `return size() * sizeof(T);`]]]]]
|
||||
[[`constexpr bool empty() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Effects][Equivalent to: `return size() == 0;`]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Element access]
|
||||
|
||||
[variablelist
|
||||
[[`constexpr reference operator[](size_type i) const;`]
|
||||
[[variablelist
|
||||
[[Preconditions][`i < size()` is `true`.]]
|
||||
[[Effects][Equivalent to: `return *(data() + i);`]]]]]
|
||||
[[`constexpr reference front() const;`]
|
||||
[[variablelist
|
||||
[[Preconditions][`empty()` is `false`.]]
|
||||
[[Effects][Equivalent to: `return *data();`]]]]]
|
||||
[[`constexpr reference back() const;`]
|
||||
[[variablelist
|
||||
[[Preconditions][`empty()` is `false`.]]
|
||||
[[Effects][Equivalent to: `return *(data() + (size() - 1);`]]]]]
|
||||
[[`constexpr pointer data() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Returns][A pointer to the first element in the span.]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Iterator support]
|
||||
|
||||
[variablelist
|
||||
[[`constexpr iterator begin() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Returns][A constant iterator referring to the first element in the span. If `empty()`,
|
||||
then it returns the same value as `cend()`.]]]]]
|
||||
[[`constexpr iterator end() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Returns][A constant iterator which is the past-the-end value.]]]]]
|
||||
[[`constexpr reverse_iterator rbegin() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Effects][Equivalent to: `return reverse_iterator(end());`]]]]]
|
||||
[[`constexpr reverse_iterator rend() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Effects][Equivalent to: `return reverse_iterator(begin());`]]]]]
|
||||
[[`constexpr const_iterator cbegin() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Returns]
|
||||
[A constant iterator referring to the first element in the span. If `empty()`,
|
||||
then it returns the same value as `cend()`.]]]]]
|
||||
[[`constexpr const_iterator cend() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Returns][A constant iterator which is the past-the-end value.]]]]]
|
||||
[[`constexpr const_reverse_iterator crbegin() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Effects][Equivalent to: `return const_reverse_iterator(cend());`]]]]]
|
||||
[[`constexpr const_reverse_iterator crend() const noexcept;`]
|
||||
[[variablelist
|
||||
[[Effects]
|
||||
[Equivalent to: `return const_reverse_iterator(cbegin());`]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Views of object representation]
|
||||
|
||||
[variablelist
|
||||
[[`template<class T, std::size_t E>
|
||||
span<const std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
|
||||
as_bytes(span<T, E> s) noexcept;`]
|
||||
[[variablelist
|
||||
[[Effects]
|
||||
[Equivalent to:
|
||||
`return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};`.]]]]]
|
||||
[[`template<class T, std::size_t E>
|
||||
span<std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
|
||||
as_writable_bytes(span<T, E> s) noexcept;`]
|
||||
[[variablelist
|
||||
[[Constraints][`is_const_v<T>` is `false`.]]
|
||||
[[Effects]
|
||||
[Equivalent to: `return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()};`
|
||||
where `R` is the return type.]]]]]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
768
doc/string_view.qbk
Normal file
768
doc/string_view.qbk
Normal file
@ -0,0 +1,768 @@
|
||||
[/
|
||||
Copyright 2021 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:string_view string_view]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/string_view.hpp>]
|
||||
|
||||
The header `<boost/core/string_view.hpp>` defines `boost::core::string_view`,
|
||||
a portable and interoperable implementation of `std::string_view`.
|
||||
|
||||
Unlike `boost::string_view`, `boost::core::string_view` has implicit
|
||||
conversions from and to `std::string_view`, which allows Boost libraries that
|
||||
support C++11/C++14 to use it in interfaces without forcing users to forgo the
|
||||
use of `std::string_view` in their code.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
template<class Ch> class basic_string_view
|
||||
{
|
||||
public:
|
||||
|
||||
// types
|
||||
|
||||
typedef std::char_traits<Ch> traits_type;
|
||||
typedef Ch value_type;
|
||||
typedef Ch* pointer;
|
||||
typedef Ch const* const_pointer;
|
||||
typedef Ch& reference;
|
||||
typedef Ch const& const_reference;
|
||||
typedef Ch const* const_iterator;
|
||||
typedef const_iterator iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef const_reverse_iterator reverse_iterator;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
// npos
|
||||
|
||||
static constexpr size_type npos = static_cast<size_type>( -1 );
|
||||
|
||||
public:
|
||||
|
||||
// construction and assignment
|
||||
|
||||
constexpr basic_string_view() noexcept;
|
||||
constexpr basic_string_view( basic_string_view const& ) noexcept = default;
|
||||
constexpr basic_string_view& operator=( basic_string_view const& ) noexcept & = default;
|
||||
constexpr basic_string_view( Ch const* str ) noexcept;
|
||||
constexpr basic_string_view( Ch const* str, size_type len ) noexcept;
|
||||
constexpr basic_string_view( Ch const* begin, Ch const* end ) noexcept;
|
||||
template<class A> basic_string_view( std::basic_string<Ch, std::char_traits<Ch>, A> const& str ) noexcept;
|
||||
basic_string_view( std::basic_string_view<Ch, std::char_traits<Ch>> const& str ) noexcept;
|
||||
|
||||
// conversions
|
||||
|
||||
template<class A> operator std::basic_string<Ch, std::char_traits<Ch>, A>() const;
|
||||
template<class Ch2> operator std::basic_string_view<Ch2>() const noexcept;
|
||||
|
||||
// iterator support
|
||||
|
||||
constexpr const_iterator begin() const noexcept;
|
||||
constexpr const_iterator end() const noexcept;
|
||||
constexpr const_iterator cbegin() const noexcept;
|
||||
constexpr const_iterator cend() const noexcept;
|
||||
constexpr const_reverse_iterator rbegin() const noexcept;
|
||||
constexpr const_reverse_iterator rend() const noexcept;
|
||||
constexpr const_reverse_iterator crbegin() const noexcept;
|
||||
constexpr const_reverse_iterator crend() const noexcept;
|
||||
|
||||
// capacity
|
||||
|
||||
constexpr size_type size() const noexcept;
|
||||
constexpr size_type length() const noexcept;
|
||||
constexpr size_type max_size() const noexcept;
|
||||
constexpr bool empty() const noexcept;
|
||||
|
||||
// element access
|
||||
|
||||
constexpr const_reference operator[]( size_type pos ) const noexcept;
|
||||
constexpr const_reference at( size_type pos ) const;
|
||||
constexpr const_reference front() const noexcept;
|
||||
constexpr const_reference back() const noexcept;
|
||||
constexpr const_pointer data() const noexcept;
|
||||
|
||||
// modifiers
|
||||
|
||||
constexpr void remove_prefix( size_type n ) noexcept;
|
||||
constexpr void remove_suffix( size_type n ) noexcept;
|
||||
constexpr void swap( basic_string_view& s ) noexcept;
|
||||
|
||||
// string operations
|
||||
|
||||
constexpr size_type copy( Ch* s, size_type n, size_type pos = 0 ) const;
|
||||
constexpr basic_string_view substr( size_type pos = 0, size_type n = npos ) const;
|
||||
|
||||
// compare
|
||||
|
||||
constexpr int compare( basic_string_view str ) const noexcept;
|
||||
constexpr int compare( size_type pos1, size_type n1, basic_string_view str ) const;
|
||||
constexpr int compare( size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2 ) const;
|
||||
constexpr int compare( Ch const* s ) const;
|
||||
constexpr int compare( size_type pos1, size_type n1, Ch const* s ) const;
|
||||
constexpr int compare( size_type pos1, size_type n1, Ch const* s, size_type n2 ) const;
|
||||
|
||||
// starts_with
|
||||
|
||||
constexpr bool starts_with( basic_string_view x ) const noexcept;
|
||||
constexpr bool starts_with( Ch x ) const noexcept;
|
||||
constexpr bool starts_with( Ch const* x ) const noexcept;
|
||||
|
||||
// ends_with
|
||||
|
||||
constexpr bool ends_with( basic_string_view x ) const noexcept;
|
||||
constexpr bool ends_with( Ch x ) const noexcept;
|
||||
constexpr bool ends_with( Ch const* x ) const noexcept;
|
||||
|
||||
// find
|
||||
|
||||
constexpr size_type find( basic_string_view str, size_type pos = 0 ) const noexcept;
|
||||
constexpr size_type find( Ch c, size_type pos = 0 ) const noexcept;
|
||||
constexpr size_type find( Ch const* s, size_type pos, size_type n ) const noexcept;
|
||||
constexpr size_type find( Ch const* s, size_type pos = 0 ) const noexcept;
|
||||
|
||||
// rfind
|
||||
|
||||
constexpr size_type rfind( basic_string_view str, size_type pos = npos ) const noexcept;
|
||||
constexpr size_type rfind( Ch c, size_type pos = npos ) const noexcept;
|
||||
constexpr size_type rfind( Ch const* s, size_type pos, size_type n ) const noexcept;
|
||||
constexpr size_type rfind( Ch const* s, size_type pos = npos ) const noexcept;
|
||||
|
||||
// find_first_of
|
||||
|
||||
constexpr size_type find_first_of( basic_string_view str, size_type pos = 0 ) const noexcept;
|
||||
constexpr size_type find_first_of( Ch c, size_type pos = 0 ) const noexcept;
|
||||
constexpr size_type find_first_of( Ch const* s, size_type pos, size_type n ) const noexcept;
|
||||
constexpr size_type find_first_of( Ch const* s, size_type pos = 0 ) const noexcept;
|
||||
|
||||
// find_last_of
|
||||
|
||||
constexpr size_type find_last_of( basic_string_view str, size_type pos = npos ) const noexcept;
|
||||
constexpr size_type find_last_of( Ch c, size_type pos = npos ) const noexcept;
|
||||
constexpr size_type find_last_of( Ch const* s, size_type pos, size_type n ) const noexcept;
|
||||
constexpr size_type find_last_of( Ch const* s, size_type pos = npos ) const noexcept;
|
||||
|
||||
// find_first_not_of
|
||||
|
||||
constexpr size_type find_first_not_of( basic_string_view str, size_type pos = 0 ) const noexcept;
|
||||
constexpr size_type find_first_not_of( Ch c, size_type pos = 0 ) const noexcept;
|
||||
constexpr size_type find_first_not_of( Ch const* s, size_type pos, size_type n ) const noexcept;
|
||||
constexpr size_type find_first_not_of( Ch const* s, size_type pos = 0 ) const noexcept;
|
||||
|
||||
// find_last_not_of
|
||||
|
||||
constexpr size_type find_last_not_of( basic_string_view str, size_type pos = npos ) const noexcept;
|
||||
constexpr size_type find_last_not_of( Ch c, size_type pos = npos ) const noexcept;
|
||||
constexpr size_type find_last_not_of( Ch const* s, size_type pos, size_type n ) const noexcept;
|
||||
constexpr size_type find_last_not_of( Ch const* s, size_type pos = npos ) const noexcept;
|
||||
|
||||
// contains
|
||||
|
||||
constexpr bool contains( basic_string_view sv ) const noexcept;
|
||||
constexpr bool contains( Ch c ) const noexcept;
|
||||
constexpr bool contains( Ch const* s ) const noexcept;
|
||||
|
||||
// relational operators
|
||||
|
||||
constexpr friend bool operator==( basic_string_view sv1, basic_string_view sv2 ) noexcept;
|
||||
constexpr friend bool operator!=( basic_string_view sv1, basic_string_view sv2 ) noexcept;
|
||||
constexpr friend bool operator<( basic_string_view sv1, basic_string_view sv2 ) noexcept;
|
||||
constexpr friend bool operator<=( basic_string_view sv1, basic_string_view sv2 ) noexcept;
|
||||
constexpr friend bool operator>( basic_string_view sv1, basic_string_view sv2 ) noexcept;
|
||||
constexpr friend bool operator>=( basic_string_view sv1, basic_string_view sv2 ) noexcept;
|
||||
};
|
||||
|
||||
// stream inserter
|
||||
|
||||
template<class Ch> std::basic_ostream<Ch>& operator<<( std::basic_ostream<Ch>& os, basic_string_view<Ch> str );
|
||||
|
||||
// typedef names
|
||||
|
||||
typedef basic_string_view<char> string_view;
|
||||
typedef basic_string_view<wchar_t> wstring_view;
|
||||
typedef basic_string_view<char16_t> u16string_view;
|
||||
typedef basic_string_view<char32_t> u32string_view;
|
||||
typedef basic_string_view<char8_t> u8string_view;
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Construction]
|
||||
|
||||
[section `constexpr basic_string_view() noexcept;`]
|
||||
|
||||
* *Ensures:* `data() == 0`; `size() == 0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr basic_string_view( Ch const* str ) noexcept;`]
|
||||
|
||||
* *Ensures:* `data() == str`; `size() == traits_type::length( str )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr basic_string_view( Ch const* str, size_type len ) noexcept;`]
|
||||
|
||||
* *Ensures:* `data() == str`; `size() == len`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr basic_string_view( Ch const* begin, Ch const* end ) noexcept;`]
|
||||
|
||||
* *Requires:* `end >= begin`.
|
||||
* *Ensures:* `data() == begin`; `size() == end - begin`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `template<class A> basic_string_view( std::basic_string<Ch, std::char_traits<Ch>, A> const& str ) noexcept;`]
|
||||
|
||||
* *Ensures:* `data() == str.data()`; `size() == str.size()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `basic_string_view( std::basic_string_view<Ch, std::char_traits<Ch>> const& str ) noexcept;`]
|
||||
|
||||
* *Ensures:* `data() == str.data()`; `size() == str.size()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Conversions]
|
||||
|
||||
[section `template<class A> operator std::basic_string<Ch, std::char_traits<Ch>, A>() const;`]
|
||||
|
||||
* *Returns:* `std::basic_string<Ch, std::char_traits<Ch>, A>( data(), size() )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `template<class Ch2> operator std::basic_string_view<Ch2>() const noexcept;`]
|
||||
|
||||
* *Constraints:* `Ch2` is the same type as `Ch`.
|
||||
* *Returns:* `std::basic_string_view<Ch2>( data(), size() )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Iterator Support]
|
||||
|
||||
[section `constexpr const_iterator begin() const noexcept;`]
|
||||
|
||||
* *Returns:* `data()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_iterator end() const noexcept;`]
|
||||
|
||||
* *Returns:* `data() + size()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_iterator cbegin() const noexcept;`]
|
||||
|
||||
* *Returns:* `begin()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_iterator cend() const noexcept;`]
|
||||
|
||||
* *Returns:* `end()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_reverse_iterator rbegin() const noexcept;`]
|
||||
|
||||
* *Returns:* `const_reverse_iterator( end() )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_reverse_iterator rend() const noexcept;`]
|
||||
|
||||
* *Returns:* `const_reverse_iterator( begin() )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_reverse_iterator crbegin() const noexcept;`]
|
||||
|
||||
* *Returns:* `rbegin()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_reverse_iterator crend() const noexcept;`]
|
||||
|
||||
* *Returns:* `rend()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Capacity]
|
||||
|
||||
[section `constexpr size_type size() const noexcept;`]
|
||||
|
||||
* *Returns:* the length of the referenced character sequence.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type length() const noexcept;`]
|
||||
|
||||
* *Returns:* `size()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type max_size() const noexcept;`]
|
||||
|
||||
* *Returns:* `std::numeric_limits<size_type>::max() / sizeof(Ch)`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr bool empty() const noexcept;`]
|
||||
|
||||
* *Returns:* `size() == 0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Element Access]
|
||||
|
||||
[section `constexpr const_reference operator[]( size_type pos ) const noexcept;`]
|
||||
|
||||
* *Requires:* `pos < size()`.
|
||||
* *Returns:* `data()[ pos ]`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_reference at( size_type pos ) const;`]
|
||||
|
||||
* *Returns:* `data()[ pos ]`.
|
||||
* *Throws:* `std::out_of_range` when `pos >= size()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_reference front() const noexcept;`]
|
||||
|
||||
* *Requires:* `!empty()`.
|
||||
* *Returns:* `data()[ 0 ]`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_reference back() const noexcept;`]
|
||||
|
||||
* *Requires:* `!empty()`.
|
||||
* *Returns:* `data()[ size() - 1 ]`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr const_pointer data() const noexcept;`]
|
||||
|
||||
* *Returns:* a pointer to the beginning of the referenced character sequence.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Modifiers]
|
||||
|
||||
[section `constexpr void remove_prefix( size_type n ) noexcept;`]
|
||||
|
||||
* *Requires:* `n <= size()`.
|
||||
* *Effects:* advances `data()` by `n` and decreases `size()` by `n`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr void remove_suffix( size_type n ) noexcept;`]
|
||||
|
||||
* *Requires:* `n <= size()`.
|
||||
* *Effects:* decreases `size()` by `n`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr void swap( basic_string_view& s ) noexcept;`]
|
||||
|
||||
* *Effects:* exchanges the contents of `*this` and `s`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section String Operations]
|
||||
|
||||
[section copy]
|
||||
|
||||
[section `constexpr size_type copy( Ch* s, size_type n, size_type pos = 0 ) const;`]
|
||||
|
||||
* *Effects:* copies to `s` the contents of `substr( pos, n )`.
|
||||
* *Throws:* `std::out_of_range` when `pos >= size()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section substr]
|
||||
|
||||
[section `constexpr basic_string_view substr( size_type pos = 0, size_type n = npos ) const;`]
|
||||
|
||||
* *Returns:* `basic_string_view( data() + pos, std::min( size() - pos, n ) )`.
|
||||
* *Throws:* `std::out_of_range` when `pos >= size()`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section compare]
|
||||
|
||||
[section `constexpr int compare( basic_string_view str ) const noexcept;`]
|
||||
|
||||
* *Returns:*
|
||||
* if `traits_type::compare( data(), str.data(), std::min( size(), str.size() ) )` is not zero, returns it. Otherwise,
|
||||
* if `size() < str.size()`, returns a negative number. Otherwise,
|
||||
* if `size() > str.size()`, returns a positive number. Otherwise,
|
||||
* returns 0.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr int compare( size_type pos1, size_type n1, basic_string_view str ) const;`]
|
||||
|
||||
* *Returns:* `substr( pos1, n1 ).compare( str )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr int compare( size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2 ) const;`]
|
||||
|
||||
* *Returns:* `substr( pos1, n1 ).compare( str.substr( pos2, n2 ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr int compare( Ch const* s ) const noexcept;`]
|
||||
|
||||
* *Returns:* `compare( basic_string_view( s ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr int compare( size_type pos1, size_type n1, Ch const* s ) const;`]
|
||||
|
||||
* *Returns:* `substr( pos1, n1 ).compare( basic_string_view( s ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr int compare( size_type pos1, size_type n1, Ch const* s, size_type n2 ) const;`]
|
||||
|
||||
* *Returns:* `substr( pos1, n1 ).compare( basic_string_view( s, n2 ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section starts_with]
|
||||
|
||||
[section `constexpr bool starts_with( basic_string_view x ) const noexcept;`]
|
||||
|
||||
* *Returns:* `substr( 0, x.size() ) == x`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr bool starts_with( Ch x ) const noexcept;`]
|
||||
|
||||
* *Returns:* `starts_with( basic_string_view( &x, 1 ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr bool starts_with( Ch const* x ) const noexcept;`]
|
||||
|
||||
* *Returns:* `starts_with( basic_string_view( x ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section ends_with]
|
||||
|
||||
[section `constexpr bool ends_with( basic_string_view x ) const noexcept;`]
|
||||
|
||||
* *Returns:* `size() >= x.size() && substr( size() - x.size(), x.size() ) == x`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr bool ends_with( Ch x ) const noexcept;`]
|
||||
|
||||
* *Returns:* `ends_with( basic_string_view( &x, 1 ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr bool ends_with( Ch const* x ) const noexcept;`]
|
||||
|
||||
* *Returns:* `ends_with( basic_string_view( x ) )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Searching]
|
||||
|
||||
[section find]
|
||||
|
||||
[section `constexpr size_type find( basic_string_view str, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* The lowest position `i` such that `i >= pos` and `substr( i, str.size() ) == str`, or `npos` if such a position doesn't exist.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find( Ch c, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find( basic_string_view( &c, 1 ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find( Ch const* s, size_type pos, size_type n ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find( basic_string_view( s, n ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find( Ch const* s, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find( basic_string_view( s ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section rfind]
|
||||
|
||||
[section `constexpr size_type rfind( basic_string_view str, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* The highest position `i` such that `i <= pos` and `substr( i, str.size() ) == str`, or `npos` if such a position doesn't exist.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type rfind( Ch c, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* `rfind( basic_string_view( &c, 1 ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type rfind( Ch const* s, size_type pos, size_type n ) const noexcept;`]
|
||||
|
||||
* *Returns:* `rfind( basic_string_view( s, n ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type rfind( Ch const* s, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* `rfind( basic_string_view( s ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section find_first_of]
|
||||
|
||||
[section `constexpr size_type find_first_of( basic_string_view str, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* The lowest position `i` such that `i >= pos` and the character at position `i` is equal to one of the characters in `str`, or `npos` if such a position doesn't exist.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_first_of( Ch c, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_first_of( basic_string_view( &c, 1 ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_first_of( Ch const* s, size_type pos, size_type n ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_first_of( basic_string_view( s, n ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_first_of( Ch const* s, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_first_of( basic_string_view( s ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section find_last_of]
|
||||
|
||||
[section `constexpr size_type find_last_of( basic_string_view str, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* The highest position `i` such that `i <= pos` and the character at position `i` is equal to one of the characters in `str`, or `npos` if such a position doesn't exist.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_last_of( Ch c, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_last_of( basic_string_view( &c, 1 ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_last_of( Ch const* s, size_type pos, size_type n ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_last_of( basic_string_view( s, n ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_last_of( Ch const* s, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_last_of( basic_string_view( s ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section find_first_not_of]
|
||||
|
||||
[section `constexpr size_type find_first_not_of( basic_string_view str, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* The lowest position `i` such that `i >= pos` and the character at position `i` is not equal to one of the characters in `str`, or `npos` if such a position doesn't exist.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_first_not_of( Ch c, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_first_not_of( basic_string_view( &c, 1 ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_first_not_of( Ch const* s, size_type pos, size_type n ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_first_not_of( basic_string_view( s, n ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_first_not_of( Ch const* s, size_type pos = 0 ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_first_not_of( basic_string_view( s ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section find_last_not_of]
|
||||
|
||||
[section `constexpr size_type find_last_not_of( basic_string_view str, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* The highest position `i` such that `i <= pos` and the character at position `i` is not equal to one of the characters in `str`, or `npos` if such a position doesn't exist.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_last_not_of( Ch c, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_last_not_of( basic_string_view( &c, 1 ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_last_not_of( Ch const* s, size_type pos, size_type n ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_last_not_of( basic_string_view( s, n ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr size_type find_last_not_of( Ch const* s, size_type pos = npos ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find_last_not_of( basic_string_view( s ), pos )`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section contains]
|
||||
|
||||
[section `constexpr bool contains( basic_string_view sv ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find( sv ) != npos`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr bool contains( Ch c ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find( c ) != npos`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr bool contains( Ch const* s ) const noexcept;`]
|
||||
|
||||
* *Returns:* `find( s ) != npos`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Relational Operators]
|
||||
|
||||
[section `constexpr friend bool operator==( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
|
||||
|
||||
* *Returns:* `sv1.compare( sv2 ) == 0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr friend bool operator!=( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
|
||||
|
||||
* *Returns:* `sv1.compare( sv2 ) != 0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr friend bool operator<( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
|
||||
|
||||
* *Returns:* `sv1.compare( sv2 ) < 0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr friend bool operator<=( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
|
||||
|
||||
* *Returns:* `sv1.compare( sv2 ) <= 0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr friend bool operator>( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
|
||||
|
||||
* *Returns:* `sv1.compare( sv2 ) > 0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section `constexpr friend bool operator>=( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
|
||||
|
||||
* *Returns:* `sv1.compare( sv2 ) >= 0`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Stream Inserter]
|
||||
|
||||
[section `template<class Ch> std::basic_ostream<Ch>& operator<<( std::basic_ostream<Ch>& os, basic_string_view<Ch> str );`]
|
||||
|
||||
* *Effects:* equivalent to `os << x`, where `x` is a pointer to a null-terminated character sequence with the same contents as `str`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
69
doc/swap.qbk
69
doc/swap.qbk
@ -20,17 +20,17 @@
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/swap.hpp>]
|
||||
[section Header <boost/core/invoke_swap.hpp>]
|
||||
|
||||
`template<class T> void swap(T& left, T& right);`
|
||||
[^template<class T> void invoke_swap(T& left, T& right) noexcept(['see below]);]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Introduction]
|
||||
|
||||
The template function `boost::swap` allows the values of two
|
||||
variables to be swapped, using argument dependent lookup to
|
||||
select a specialized swap function if available. If no
|
||||
The template function `boost::core::invoke_swap` allows the
|
||||
values of two variables to be swapped, using argument dependent
|
||||
lookup to select a specialized swap function if available. If no
|
||||
specialized swap function is available, `std::swap` is used.
|
||||
|
||||
[endsect]
|
||||
@ -40,13 +40,14 @@ specialized swap function is available, `std::swap` is used.
|
||||
The generic `std::swap` function requires that the elements
|
||||
to be swapped are assignable and copy constructible. It is
|
||||
usually implemented using one copy construction and two
|
||||
assignments - this is often both unnecessarily restrictive and
|
||||
unnecessarily slow. In addition, where the generic swap
|
||||
implementation provides only the basic guarantee, specialized
|
||||
swap functions are often able to provide the no-throw exception
|
||||
guarantee (and it is considered best practice to do so where
|
||||
possible [footnote Scott Meyers, Effective C++ Third Edition,
|
||||
Item 25: "Consider support for a non-throwing swap"].
|
||||
assignments (C++11 replaces copy operations with move) - this
|
||||
is often both unnecessarily restrictive and unnecessarily slow.
|
||||
In addition, where the generic swap implementation provides
|
||||
only the basic guarantee, specialized swap functions are often
|
||||
able to provide the no-throw exception guarantee (and it is
|
||||
considered best practice to do so where possible[footnote Scott
|
||||
Meyers, Effective C++ Third Edition, Item 25: "Consider support
|
||||
for a non-throwing swap"].
|
||||
|
||||
The alternative to using argument dependent lookup in this
|
||||
situation is to provide a template specialization of
|
||||
@ -55,23 +56,27 @@ Although this is legal C++, no Boost libraries use this method,
|
||||
whereas many Boost libraries provide specialized swap functions
|
||||
in their own namespaces.
|
||||
|
||||
`boost::swap` also supports swapping built-in arrays. Note that
|
||||
`std::swap` originally did not do so, but a request to add an
|
||||
overload of `std::swap` for built-in arrays has been accepted
|
||||
`boost::core::invoke_swap` also supports swapping built-in arrays.
|
||||
Note that `std::swap` originally did not do so, but a request to
|
||||
add an overload of `std::swap` for built-in arrays has been accepted
|
||||
by the C++ Standards Committee[footnote
|
||||
[@http://open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#809
|
||||
[@http://open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#809
|
||||
LWG Defect Report 809: std::swap should be overloaded for array
|
||||
types]].
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Exception Safety]
|
||||
|
||||
`boost::swap` provides the same exception guarantee as the
|
||||
underlying swap function used, with one exception; for an array
|
||||
`boost::core::invoke_swap` provides the same exception guarantee as
|
||||
the underlying swap function used, with one exception; for an array
|
||||
of type `T[n]`, where `n > 1` and the underlying swap function
|
||||
for `T` provides the strong exception guarantee, `boost::swap`
|
||||
provides only the basic exception guarantee.
|
||||
for `T` provides the strong exception guarantee,
|
||||
`boost::core::invoke_swap` provides only the basic exception guarantee.
|
||||
|
||||
In C++11 and later, `boost::core::invoke_swap` propagates the same
|
||||
`noexcept` specification as the one specified in the underlying swap
|
||||
function.
|
||||
|
||||
[endsect]
|
||||
|
||||
@ -79,42 +84,44 @@ provides only the basic exception guarantee.
|
||||
|
||||
Either:
|
||||
|
||||
* T must be assignable
|
||||
* T must be copy constructible
|
||||
* `T` must be copy assignable (/since C++11:/ move assignable)
|
||||
* `T` must be copy constructible (/since C++11:/ move constructible)
|
||||
|
||||
Or:
|
||||
|
||||
* A function with the signature `swap(T&,T&)` is available via
|
||||
* A function with the signature `swap(T&, T&)` is available via
|
||||
argument dependent lookup
|
||||
|
||||
Or:
|
||||
|
||||
* A template specialization of `std::swap` exists for T
|
||||
* A template specialization of `std::swap` exists for `T`
|
||||
|
||||
Or:
|
||||
|
||||
* T is a built-in array of swappable elements
|
||||
* `T` is a built-in array of swappable elements
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Portability]
|
||||
|
||||
Several older compilers do not support argument dependent
|
||||
lookup. On these compilers `boost::swap` will call
|
||||
lookup. On these compilers `boost::core::invoke_swap` will call
|
||||
`std::swap`, ignoring any specialized swap functions that
|
||||
could be found as a result of argument dependent lookup.
|
||||
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
[section Credits]
|
||||
|
||||
* *Niels Dekker* - for implementing and documenting support for
|
||||
* *Niels Dekker* - for implementing and documenting support for
|
||||
built-in arrays
|
||||
* *Joseph Gauterin* - for the initial idea, implementation,
|
||||
tests, and documentation
|
||||
* *Steven Watanabe* - for the idea to make `boost::swap` less
|
||||
specialized than `std::swap`, thereby allowing the function
|
||||
to have the name 'swap' without introducing ambiguity
|
||||
to have the name 'swap' without introducing ambiguity. However,
|
||||
later the function was renamed to `boost::core::invoke_swap`
|
||||
to avoid potential infinite recursion.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
77
doc/type_name.qbk
Normal file
77
doc/type_name.qbk
Normal file
@ -0,0 +1,77 @@
|
||||
[/
|
||||
Copyright 2021 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:type_name type_name]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/type_name.hpp>]
|
||||
|
||||
The header `<boost/core/type_name.hpp>` defines the function
|
||||
template `boost::core::type_name<T>()` that returns a string
|
||||
representation of the name of `T`, suitable for logging or
|
||||
diagnostic display purposes.
|
||||
|
||||
The result is similar to `boost::core::demangle( typeid(T).name() )`,
|
||||
but it's made more regular by eliminating some of the platform-specific
|
||||
differences and extra template parameters of the standard library
|
||||
container types.
|
||||
|
||||
For example, `type_name< std::map<std::string, int> >()` returns
|
||||
`"std::map<std::string, int>"` and not
|
||||
|
||||
```
|
||||
std::map<std::__cxx11::basic_string<char, std::char_traits<char>,
|
||||
std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char,
|
||||
std::char_traits<char>, std::allocator<char> > >, std::allocator<
|
||||
std::pair<std::__cxx11::basic_string<char, std::char_traits<char>,
|
||||
std::allocator<char> > const, int> > >
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
class std::map<class std::basic_string<char,struct std::char_traits<char>,
|
||||
class std::allocator<char> >,int,struct std::less<class std::basic_string<
|
||||
char,struct std::char_traits<char>,class std::allocator<char> > >,class
|
||||
std::allocator<struct std::pair<class std::basic_string<char,struct
|
||||
std::char_traits<char>,class std::allocator<char> > const ,int> > >
|
||||
```
|
||||
|
||||
The return values aren't guaranteed to be stable across Boost releases.
|
||||
|
||||
Compilation with `-fno-rtti` is supported, but the returned type names aren't
|
||||
guaranteed to be particularly useful or unique.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
template<class T> std::string type_name();
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[section template<class T> std::string type_name();]
|
||||
|
||||
* *Returns:* A string representation of the name of `T`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
@ -11,7 +11,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
[section Overview]
|
||||
|
||||
The header <boost/core/use_default.hpp> provides the type `boost::use_default`
|
||||
which is used by other Boost libraries as a sentinel type in a templates to
|
||||
which is used by other Boost libraries as a sentinel type in templates to
|
||||
indicate defaults.
|
||||
|
||||
[endsect]
|
||||
|
70
doc/verbose_terminate_handler.qbk
Normal file
70
doc/verbose_terminate_handler.qbk
Normal file
@ -0,0 +1,70 @@
|
||||
[/
|
||||
Copyright 2022 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:verbose_terminate_handler verbose_terminate_handler]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/verbose_terminate_handler.hpp>]
|
||||
|
||||
The header `<boost/core/verbose_terminate_handler.hpp>` defines
|
||||
the function `void boost::core::verbose_terminate_handler()`. Its
|
||||
purpose is to be set as a terminate handler as in
|
||||
```
|
||||
std::set_terminate( boost::core::verbose_terminate_handler );
|
||||
```
|
||||
|
||||
When invoked, the function prints information about the current
|
||||
uncaught exception to `stderr` and then calls `std::abort`.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
[[noreturn]] void verbose_terminate_handler();
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Example]
|
||||
|
||||
```
|
||||
#include <boost/core/verbose_terminate_handler.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <exception>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::set_terminate( boost::core::verbose_terminate_handler );
|
||||
boost::throw_with_location( std::exception() );
|
||||
}
|
||||
```
|
||||
|
||||
Sample output:
|
||||
```
|
||||
std::terminate called after throwing an exception:
|
||||
|
||||
type: class boost::detail::with_throw_location<class std::exception>
|
||||
what(): Unknown exception
|
||||
location: example.cpp:8:12 in function 'main'
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
79
doc/yield_primitives.qbk
Normal file
79
doc/yield_primitives.qbk
Normal file
@ -0,0 +1,79 @@
|
||||
[/
|
||||
Copyright 2023 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://boost.org/LICENSE_1_0.txt
|
||||
]
|
||||
|
||||
[section:yield_primitives Yield Primitives]
|
||||
|
||||
[simplesect Authors]
|
||||
|
||||
* Peter Dimov
|
||||
|
||||
[endsimplesect]
|
||||
|
||||
[section Header <boost/core/yield_primitives.hpp>]
|
||||
|
||||
The header `<boost/core/yield_primitives.hpp>` implements a
|
||||
collection of primitives that allow the current thread to
|
||||
yield the CPU in various ways.
|
||||
|
||||
Very low level, specialized functionality, generally only useful for
|
||||
implementing spinlocks. Normal synchronization primitives should
|
||||
almost always be preferable in application code.
|
||||
|
||||
[section Synopsis]
|
||||
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
void sp_thread_pause() noexcept;
|
||||
void sp_thread_yield() noexcept;
|
||||
void sp_thread_sleep() noexcept;
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[section sp_thread_pause]
|
||||
|
||||
`void sp_thread_pause() noexcept;`
|
||||
|
||||
Emits a PAUSE instruction (on x86) or a YIELD instruction (on ARM).
|
||||
|
||||
A portable equivalent of the GCC builtin function `__builtin_ia32_pause`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section sp_thread_yield]
|
||||
|
||||
`void sp_thread_yield() noexcept;`
|
||||
|
||||
Informs the scheduler that the current thread wishes to relinquish
|
||||
the rest of its timeslice.
|
||||
|
||||
A portable equivalent of POSIX `sched_yield`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section sp_thread_sleep]
|
||||
|
||||
`void sp_thread_sleep() noexcept;`
|
||||
|
||||
Sleeps for a short period, as if by calling POSIX `nanosleep` with
|
||||
a small, implementation-dependent, interval (usually one microsecond).
|
||||
|
||||
A more forcing yield primitive than `sp_thread_yield`, because it's
|
||||
generally not ignored even if all other waiting threads are of lower
|
||||
priority.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
8
extra/boost_core.natvis
Normal file
8
extra/boost_core.natvis
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
|
||||
<Type Name="boost::core::basic_string_view<*>">
|
||||
<DisplayString>{p_,[n_]s}</DisplayString>
|
||||
</Type>
|
||||
|
||||
</AutoVisualizer>
|
@ -125,7 +125,7 @@ template<class T>
|
||||
BOOST_FORCEINLINE T*
|
||||
addressof(T& o) BOOST_NOEXCEPT
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) || \
|
||||
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x610)) || \
|
||||
BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)
|
||||
return boost::detail::addrof<T>::get(o, 0);
|
||||
#else
|
||||
@ -151,7 +151,7 @@ addressof(T (&o)[N]) BOOST_NOEXCEPT
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
|
||||
template<class T, std::size_t N>
|
||||
BOOST_FORCEINLINE
|
||||
T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N]
|
||||
|
57
include/boost/core/alignof.hpp
Normal file
57
include/boost/core/alignof.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef BOOST_CORE_ALIGNOF_HPP_INCLUDED
|
||||
#define BOOST_CORE_ALIGNOF_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALIGNOF)
|
||||
|
||||
#define BOOST_CORE_ALIGNOF alignof
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#define BOOST_CORE_ALIGNOF __alignof__
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#define BOOST_CORE_ALIGNOF __alignof
|
||||
|
||||
#else
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct alignof_helper
|
||||
{
|
||||
char x;
|
||||
T t;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// ignoring -Wvariadic-macros with #pragma doesn't work under GCC
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#define BOOST_CORE_ALIGNOF(...) offsetof( ::boost::core::detail::alignof_helper<__VA_ARGS__>, t );
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_CORE_ALIGNOF_HPP_INCLUDED
|
@ -8,79 +8,32 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef BOOST_CORE_ALLOC_CONSTRUCT_HPP
|
||||
#define BOOST_CORE_ALLOC_CONSTRUCT_HPP
|
||||
|
||||
/*
|
||||
This functionality is now in <boost/core/allocator_access.hpp>.
|
||||
*/
|
||||
#include <boost/core/noinit_adaptor.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_destroy(A& a, T* p)
|
||||
{
|
||||
std::allocator_traits<A>::destroy(a, p);
|
||||
boost::allocator_destroy(a, p);
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_destroy_n(A& a, T* p, std::size_t n)
|
||||
{
|
||||
while (n > 0) {
|
||||
std::allocator_traits<A>::destroy(a, p + --n);
|
||||
}
|
||||
}
|
||||
#else
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_destroy(A&, T* p)
|
||||
{
|
||||
p->~T();
|
||||
boost::allocator_destroy_n(a, p, n);
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_destroy_n(A&, T* p, std::size_t n)
|
||||
{
|
||||
while (n > 0) {
|
||||
p[--n].~T();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class T>
|
||||
class alloc_destroyer {
|
||||
public:
|
||||
alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
|
||||
: a_(a),
|
||||
p_(p),
|
||||
n_(0) { }
|
||||
|
||||
~alloc_destroyer() {
|
||||
boost::alloc_destroy_n(a_, p_, n_);
|
||||
}
|
||||
|
||||
std::size_t& size() BOOST_NOEXCEPT {
|
||||
return n_;
|
||||
}
|
||||
|
||||
private:
|
||||
alloc_destroyer(const alloc_destroyer&);
|
||||
alloc_destroyer& operator=(const alloc_destroyer&);
|
||||
|
||||
A& a_;
|
||||
T* p_;
|
||||
std::size_t n_;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_construct(A& a, T* p)
|
||||
{
|
||||
std::allocator_traits<A>::construct(a, p);
|
||||
boost::allocator_construct(a, p);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
@ -89,7 +42,7 @@ template<class A, class T, class U, class... V>
|
||||
inline void
|
||||
alloc_construct(A& a, T* p, U&& u, V&&... v)
|
||||
{
|
||||
std::allocator_traits<A>::construct(a, p, std::forward<U>(u),
|
||||
boost::allocator_construct(a, p, std::forward<U>(u),
|
||||
std::forward<V>(v)...);
|
||||
}
|
||||
#else
|
||||
@ -97,7 +50,7 @@ template<class A, class T, class U>
|
||||
inline void
|
||||
alloc_construct(A& a, T* p, U&& u)
|
||||
{
|
||||
std::allocator_traits<A>::construct(a, p, std::forward<U>(u));
|
||||
boost::allocator_construct(a, p, std::forward<U>(u));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
@ -105,14 +58,14 @@ template<class A, class T, class U>
|
||||
inline void
|
||||
alloc_construct(A& a, T* p, const U& u)
|
||||
{
|
||||
std::allocator_traits<A>::construct(a, p, u);
|
||||
boost::allocator_construct(a, p, u);
|
||||
}
|
||||
|
||||
template<class A, class T, class U>
|
||||
inline void
|
||||
alloc_construct(A& a, T* p, U& u)
|
||||
{
|
||||
std::allocator_traits<A>::construct(a, p, u);
|
||||
boost::allocator_construct(a, p, u);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -120,125 +73,22 @@ template<class A, class T>
|
||||
inline void
|
||||
alloc_construct_n(A& a, T* p, std::size_t n)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> hold(a, p);
|
||||
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||
std::allocator_traits<A>::construct(a, p + i);
|
||||
}
|
||||
hold.size() = 0;
|
||||
boost::allocator_construct_n(a, p, n);
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> hold(a, p);
|
||||
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||
std::allocator_traits<A>::construct(a, p + i, l[i % m]);
|
||||
}
|
||||
hold.size() = 0;
|
||||
boost::allocator_construct_n(a, p, n, l, m);
|
||||
}
|
||||
|
||||
template<class A, class T, class I>
|
||||
inline void
|
||||
alloc_construct_n(A& a, T* p, std::size_t n, I b)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> hold(a, p);
|
||||
for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
|
||||
std::allocator_traits<A>::construct(a, p + i, *b);
|
||||
}
|
||||
hold.size() = 0;
|
||||
boost::allocator_construct_n(a, p, n, b);
|
||||
}
|
||||
#else
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_construct(A&, T* p)
|
||||
{
|
||||
::new(static_cast<void*>(p)) T();
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_construct(noinit_adaptor<A>&, T* p)
|
||||
{
|
||||
::new(static_cast<void*>(p)) T;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class A, class T, class U, class... V>
|
||||
inline void
|
||||
alloc_construct(A&, T* p, U&& u, V&&... v)
|
||||
{
|
||||
::new(static_cast<void*>(p)) T(std::forward<U>(u), std::forward<V>(v)...);
|
||||
}
|
||||
#else
|
||||
template<class A, class T, class U>
|
||||
inline void
|
||||
alloc_construct(A& a, T* p, U&& u)
|
||||
{
|
||||
::new(static_cast<void*>(p)) T(std::forward<U>(u));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
template<class A, class T, class U>
|
||||
inline void
|
||||
alloc_construct(A&, T* p, const U& u)
|
||||
{
|
||||
::new(static_cast<void*>(p)) T(u);
|
||||
}
|
||||
|
||||
template<class A, class T, class U>
|
||||
inline void
|
||||
alloc_construct(A&, T* p, U& u)
|
||||
{
|
||||
::new(static_cast<void*>(p)) T(u);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_construct_n(A& a, T* p, std::size_t n)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> hold(a, p);
|
||||
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||
::new(static_cast<void*>(p + i)) T();
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_construct_n(noinit_adaptor<A>& a, T* p, std::size_t n)
|
||||
{
|
||||
detail::alloc_destroyer<noinit_adaptor<A>, T> hold(a, p);
|
||||
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||
::new(static_cast<void*>(p + i)) T;
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> hold(a, p);
|
||||
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||
::new(static_cast<void*>(p + i)) T(l[i % m]);
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
|
||||
template<class A, class T, class I>
|
||||
inline void
|
||||
alloc_construct_n(A& a, T* p, std::size_t n, I b)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> hold(a, p);
|
||||
for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
|
||||
::new(static_cast<void*>(p + i)) T(*b);
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* boost */
|
||||
|
||||
|
834
include/boost/core/allocator_access.hpp
Normal file
834
include/boost/core/allocator_access.hpp
Normal file
@ -0,0 +1,834 @@
|
||||
/*
|
||||
Copyright 2020-2022 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_CORE_ALLOCATOR_ACCESS_HPP
|
||||
#define BOOST_CORE_ALLOCATOR_ACCESS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/pointer_traits.hpp>
|
||||
#include <limits>
|
||||
#include <new>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40300)
|
||||
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
|
||||
#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
|
||||
#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
|
||||
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
|
||||
#elif defined(BOOST_CLANG) && !defined(__CUDACC__)
|
||||
#if __has_feature(is_empty)
|
||||
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
|
||||
#endif
|
||||
#elif defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)
|
||||
#define BOOST_DETAIL_ALLOC_EMPTY(T) __oracle_is_empty(T)
|
||||
#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
|
||||
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
|
||||
#elif defined(BOOST_CODEGEARC)
|
||||
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
|
||||
#endif
|
||||
|
||||
#if defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH)
|
||||
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
|
||||
#endif
|
||||
#if defined(_STL_DISABLE_DEPRECATED_WARNING)
|
||||
_STL_DISABLE_DEPRECATED_WARNING
|
||||
#endif
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wdeprecated-declarations")
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4996)
|
||||
#elif defined(BOOST_GCC) && BOOST_GCC >= 40600
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class A>
|
||||
struct allocator_value_type {
|
||||
typedef typename A::value_type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class = void>
|
||||
struct alloc_ptr {
|
||||
typedef typename boost::allocator_value_type<A>::type* type;
|
||||
};
|
||||
|
||||
template<class>
|
||||
struct alloc_void {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_ptr<A,
|
||||
typename alloc_void<typename A::pointer>::type> {
|
||||
typedef typename A::pointer type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_pointer {
|
||||
typedef typename detail::alloc_ptr<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class = void>
|
||||
struct alloc_const_ptr {
|
||||
typedef typename boost::pointer_traits<typename
|
||||
boost::allocator_pointer<A>::type>::template rebind_to<const typename
|
||||
boost::allocator_value_type<A>::type>::type type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_const_ptr<A,
|
||||
typename alloc_void<typename A::const_pointer>::type> {
|
||||
typedef typename A::const_pointer type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_const_pointer {
|
||||
typedef typename detail::alloc_const_ptr<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class, class>
|
||||
struct alloc_to { };
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<template<class> class A, class T, class U>
|
||||
struct alloc_to<A<U>, T> {
|
||||
typedef A<T> type;
|
||||
};
|
||||
|
||||
template<template<class, class> class A, class T, class U, class V>
|
||||
struct alloc_to<A<U, V>, T> {
|
||||
typedef A<T, V> type;
|
||||
};
|
||||
|
||||
template<template<class, class, class> class A, class T, class U, class V1,
|
||||
class V2>
|
||||
struct alloc_to<A<U, V1, V2>, T> {
|
||||
typedef A<T, V1, V2> type;
|
||||
};
|
||||
#else
|
||||
template<template<class, class...> class A, class T, class U, class... V>
|
||||
struct alloc_to<A<U, V...>, T> {
|
||||
typedef A<T, V...> type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class A, class T, class = void>
|
||||
struct alloc_rebind {
|
||||
typedef typename alloc_to<A, T>::type type;
|
||||
};
|
||||
|
||||
template<class A, class T>
|
||||
struct alloc_rebind<A, T,
|
||||
typename alloc_void<typename A::template rebind<T>::other>::type> {
|
||||
typedef typename A::template rebind<T>::other type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A, class T>
|
||||
struct allocator_rebind {
|
||||
typedef typename detail::alloc_rebind<A, T>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class = void>
|
||||
struct alloc_void_ptr {
|
||||
typedef typename boost::pointer_traits<typename
|
||||
boost::allocator_pointer<A>::type>::template
|
||||
rebind_to<void>::type type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_void_ptr<A,
|
||||
typename alloc_void<typename A::void_pointer>::type> {
|
||||
typedef typename A::void_pointer type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_void_pointer {
|
||||
typedef typename detail::alloc_void_ptr<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class = void>
|
||||
struct alloc_const_void_ptr {
|
||||
typedef typename boost::pointer_traits<typename
|
||||
boost::allocator_pointer<A>::type>::template
|
||||
rebind_to<const void>::type type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_const_void_ptr<A,
|
||||
typename alloc_void<typename A::const_void_pointer>::type> {
|
||||
typedef typename A::const_void_pointer type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_const_void_pointer {
|
||||
typedef typename detail::alloc_const_void_ptr<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class = void>
|
||||
struct alloc_diff_type {
|
||||
typedef typename boost::pointer_traits<typename
|
||||
boost::allocator_pointer<A>::type>::difference_type type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_diff_type<A,
|
||||
typename alloc_void<typename A::difference_type>::type> {
|
||||
typedef typename A::difference_type type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_difference_type {
|
||||
typedef typename detail::alloc_diff_type<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A, class = void>
|
||||
struct alloc_size_type {
|
||||
typedef std::size_t type;
|
||||
};
|
||||
#else
|
||||
template<class A, class = void>
|
||||
struct alloc_size_type {
|
||||
typedef typename std::make_unsigned<typename
|
||||
boost::allocator_difference_type<A>::type>::type type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class A>
|
||||
struct alloc_size_type<A,
|
||||
typename alloc_void<typename A::size_type>::type> {
|
||||
typedef typename A::size_type type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_size_type {
|
||||
typedef typename detail::alloc_size_type<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<bool V>
|
||||
struct alloc_bool {
|
||||
typedef bool value_type;
|
||||
typedef alloc_bool type;
|
||||
|
||||
static const bool value = V;
|
||||
|
||||
operator bool() const BOOST_NOEXCEPT {
|
||||
return V;
|
||||
}
|
||||
|
||||
bool operator()() const BOOST_NOEXCEPT {
|
||||
return V;
|
||||
}
|
||||
};
|
||||
|
||||
template<bool V>
|
||||
const bool alloc_bool<V>::value;
|
||||
|
||||
typedef alloc_bool<false> alloc_false;
|
||||
#else
|
||||
typedef std::false_type alloc_false;
|
||||
#endif
|
||||
|
||||
template<class A, class = void>
|
||||
struct alloc_pocca {
|
||||
typedef alloc_false type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_pocca<A,
|
||||
typename alloc_void<typename
|
||||
A::propagate_on_container_copy_assignment>::type> {
|
||||
typedef typename A::propagate_on_container_copy_assignment type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A, class = void>
|
||||
struct allocator_propagate_on_container_copy_assignment {
|
||||
typedef typename detail::alloc_pocca<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class = void>
|
||||
struct alloc_pocma {
|
||||
typedef alloc_false type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_pocma<A,
|
||||
typename alloc_void<typename
|
||||
A::propagate_on_container_move_assignment>::type> {
|
||||
typedef typename A::propagate_on_container_move_assignment type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_propagate_on_container_move_assignment {
|
||||
typedef typename detail::alloc_pocma<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class = void>
|
||||
struct alloc_pocs {
|
||||
typedef alloc_false type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_pocs<A,
|
||||
typename alloc_void<typename A::propagate_on_container_swap>::type> {
|
||||
typedef typename A::propagate_on_container_swap type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_propagate_on_container_swap {
|
||||
typedef typename detail::alloc_pocs<A>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A, class = void>
|
||||
struct alloc_equal {
|
||||
typedef typename std::is_empty<A>::type type;
|
||||
};
|
||||
#elif defined(BOOST_DETAIL_ALLOC_EMPTY)
|
||||
template<class A, class = void>
|
||||
struct alloc_equal {
|
||||
typedef alloc_bool<BOOST_DETAIL_ALLOC_EMPTY(A)> type;
|
||||
};
|
||||
#else
|
||||
template<class A, class = void>
|
||||
struct alloc_equal {
|
||||
typedef alloc_false type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class A>
|
||||
struct alloc_equal<A,
|
||||
typename alloc_void<typename A::is_always_equal>::type> {
|
||||
typedef typename A::is_always_equal type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
struct allocator_is_always_equal {
|
||||
typedef typename detail::alloc_equal<A>::type type;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
inline typename allocator_pointer<A>::type
|
||||
allocator_allocate(A& a, typename allocator_size_type<A>::type n)
|
||||
{
|
||||
return a.allocate(n);
|
||||
}
|
||||
|
||||
template<class A>
|
||||
inline void
|
||||
allocator_deallocate(A& a, typename allocator_pointer<A>::type p,
|
||||
typename allocator_size_type<A>::type n)
|
||||
{
|
||||
a.deallocate(p, n);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A>
|
||||
inline typename allocator_pointer<A>::type
|
||||
allocator_allocate(A& a, typename allocator_size_type<A>::type n,
|
||||
typename allocator_const_void_pointer<A>::type h)
|
||||
{
|
||||
return a.allocate(n, h);
|
||||
}
|
||||
#else
|
||||
namespace detail {
|
||||
|
||||
template<class>
|
||||
struct alloc_no {
|
||||
char x, y;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
class alloc_has_allocate {
|
||||
template<class O>
|
||||
static auto check(int)
|
||||
-> alloc_no<decltype(std::declval<O&>().allocate(std::declval<typename
|
||||
boost::allocator_size_type<A>::type>(), std::declval<typename
|
||||
boost::allocator_const_void_pointer<A>::type>()))>;
|
||||
|
||||
template<class>
|
||||
static char check(long);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
inline typename std::enable_if<detail::alloc_has_allocate<A>::value,
|
||||
typename allocator_pointer<A>::type>::type
|
||||
allocator_allocate(A& a, typename allocator_size_type<A>::type n,
|
||||
typename allocator_const_void_pointer<A>::type h)
|
||||
{
|
||||
return a.allocate(n, h);
|
||||
}
|
||||
|
||||
template<class A>
|
||||
inline typename std::enable_if<!detail::alloc_has_allocate<A>::value,
|
||||
typename allocator_pointer<A>::type>::type
|
||||
allocator_allocate(A& a, typename allocator_size_type<A>::type n,
|
||||
typename allocator_const_void_pointer<A>::type)
|
||||
{
|
||||
return a.allocate(n);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A, class = void>
|
||||
struct alloc_has_construct {
|
||||
BOOST_STATIC_CONSTEXPR bool value = false;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct alloc_has_construct<A,
|
||||
typename alloc_void<typename A::_default_construct_destroy>::type> {
|
||||
BOOST_STATIC_CONSTEXPR bool value = true;
|
||||
};
|
||||
#else
|
||||
template<class A, class T, class... Args>
|
||||
class alloc_has_construct {
|
||||
template<class O>
|
||||
static auto check(int)
|
||||
-> alloc_no<decltype(std::declval<O&>().construct(std::declval<T*>(),
|
||||
std::declval<Args&&>()...))>;
|
||||
|
||||
template<class>
|
||||
static char check(long);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<bool, class = void>
|
||||
struct alloc_if { };
|
||||
|
||||
template<class T>
|
||||
struct alloc_if<true, T> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A, class T>
|
||||
inline typename detail::alloc_if<detail::alloc_has_construct<A>::value>::type
|
||||
allocator_construct(A& a, T* p)
|
||||
{
|
||||
a.construct(p);
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline typename detail::alloc_if<!detail::alloc_has_construct<A>::value>::type
|
||||
allocator_construct(A&, T* p)
|
||||
{
|
||||
::new((void*)p) T();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class A, class T, class V, class... Args>
|
||||
inline void
|
||||
allocator_construct(A&, T* p, V&& v, Args&&... args)
|
||||
{
|
||||
::new((void*)p) T(std::forward<V>(v), std::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
template<class A, class T, class V>
|
||||
inline void
|
||||
allocator_construct(A&, T* p, V&& v)
|
||||
{
|
||||
::new((void*)p) T(std::forward<V>(v));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
template<class A, class T, class V>
|
||||
inline void
|
||||
allocator_construct(A&, T* p, const V& v)
|
||||
{
|
||||
::new((void*)p) T(v);
|
||||
}
|
||||
|
||||
template<class A, class T, class V>
|
||||
inline void
|
||||
allocator_construct(A&, T* p, V& v)
|
||||
{
|
||||
::new((void*)p) T(v);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
template<class A, class T, class... Args>
|
||||
inline typename std::enable_if<detail::alloc_has_construct<A, T,
|
||||
Args...>::value>::type
|
||||
allocator_construct(A& a, T* p, Args&&... args)
|
||||
{
|
||||
a.construct(p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<class A, class T, class... Args>
|
||||
inline typename std::enable_if<!detail::alloc_has_construct<A, T,
|
||||
Args...>::value>::type
|
||||
allocator_construct(A&, T* p, Args&&... args)
|
||||
{
|
||||
::new((void*)p) T(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A, class, class = void>
|
||||
struct alloc_has_destroy {
|
||||
BOOST_STATIC_CONSTEXPR bool value = false;
|
||||
};
|
||||
|
||||
template<class A, class T>
|
||||
struct alloc_has_destroy<A, T,
|
||||
typename alloc_void<typename A::_default_construct_destroy>::type> {
|
||||
BOOST_STATIC_CONSTEXPR bool value = true;
|
||||
};
|
||||
#else
|
||||
template<class A, class T>
|
||||
class alloc_has_destroy {
|
||||
template<class O>
|
||||
static auto check(int)
|
||||
-> alloc_no<decltype(std::declval<O&>().destroy(std::declval<T*>()))>;
|
||||
|
||||
template<class>
|
||||
static char check(long);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A, class T>
|
||||
inline typename detail::alloc_if<detail::alloc_has_destroy<A, T>::value>::type
|
||||
allocator_destroy(A& a, T* p)
|
||||
{
|
||||
a.destroy(p);
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline typename detail::alloc_if<!detail::alloc_has_destroy<A, T>::value>::type
|
||||
allocator_destroy(A&, T* p)
|
||||
{
|
||||
p->~T();
|
||||
(void)p;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class T, T>
|
||||
struct alloc_no {
|
||||
char x, y;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
class alloc_has_max_size {
|
||||
template<class O>
|
||||
static alloc_no<typename boost::allocator_size_type<O>::type(O::*)(),
|
||||
&O::max_size> check(int);
|
||||
|
||||
template<class O>
|
||||
static alloc_no<typename boost::allocator_size_type<O>::type(O::*)() const,
|
||||
&O::max_size> check(int);
|
||||
|
||||
template<class O>
|
||||
static alloc_no<typename boost::allocator_size_type<O>::type(*)(),
|
||||
&O::max_size> check(int);
|
||||
|
||||
template<class>
|
||||
static char check(long);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
|
||||
};
|
||||
#else
|
||||
template<class A>
|
||||
class alloc_has_max_size {
|
||||
template<class O>
|
||||
static auto check(int)
|
||||
-> alloc_no<decltype(std::declval<const O&>().max_size())>;
|
||||
|
||||
template<class>
|
||||
static char check(long);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
inline typename detail::alloc_if<detail::alloc_has_max_size<A>::value,
|
||||
typename allocator_size_type<A>::type>::type
|
||||
allocator_max_size(const A& a) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.max_size();
|
||||
}
|
||||
|
||||
template<class A>
|
||||
inline typename detail::alloc_if<!detail::alloc_has_max_size<A>::value,
|
||||
typename allocator_size_type<A>::type>::type
|
||||
allocator_max_size(const A&) BOOST_NOEXCEPT
|
||||
{
|
||||
return (std::numeric_limits<typename
|
||||
allocator_size_type<A>::type>::max)() /
|
||||
sizeof(typename allocator_value_type<A>::type);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A>
|
||||
class alloc_has_soccc {
|
||||
template<class O>
|
||||
static alloc_no<O(O::*)(), &O::select_on_container_copy_construction>
|
||||
check(int);
|
||||
|
||||
template<class O>
|
||||
static alloc_no<O(O::*)() const, &O::select_on_container_copy_construction>
|
||||
check(int);
|
||||
|
||||
template<class O>
|
||||
static alloc_no<O(*)(), &O::select_on_container_copy_construction>
|
||||
check(int);
|
||||
|
||||
template<class>
|
||||
static char check(long);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
|
||||
};
|
||||
#else
|
||||
template<class A>
|
||||
class alloc_has_soccc {
|
||||
template<class O>
|
||||
static auto check(int) -> alloc_no<decltype(std::declval<const
|
||||
O&>().select_on_container_copy_construction())>;
|
||||
|
||||
template<class>
|
||||
static char check(long);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A>
|
||||
inline typename detail::alloc_if<detail::alloc_has_soccc<A>::value, A>::type
|
||||
allocator_select_on_container_copy_construction(const A& a)
|
||||
{
|
||||
return a.select_on_container_copy_construction();
|
||||
}
|
||||
|
||||
template<class A>
|
||||
inline typename detail::alloc_if<!detail::alloc_has_soccc<A>::value, A>::type
|
||||
allocator_select_on_container_copy_construction(const A& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
allocator_destroy_n(A& a, T* p, std::size_t n)
|
||||
{
|
||||
while (n > 0) {
|
||||
boost::allocator_destroy(a, p + --n);
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class A, class T>
|
||||
class alloc_destroyer {
|
||||
public:
|
||||
alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
|
||||
: a_(a), p_(p), n_(0) { }
|
||||
|
||||
~alloc_destroyer() {
|
||||
boost::allocator_destroy_n(a_, p_, n_);
|
||||
}
|
||||
|
||||
std::size_t& size() BOOST_NOEXCEPT {
|
||||
return n_;
|
||||
}
|
||||
|
||||
private:
|
||||
alloc_destroyer(const alloc_destroyer&);
|
||||
alloc_destroyer& operator=(const alloc_destroyer&);
|
||||
|
||||
A& a_;
|
||||
T* p_;
|
||||
std::size_t n_;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
allocator_construct_n(A& a, T* p, std::size_t n)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> d(a, p);
|
||||
for (std::size_t& i = d.size(); i < n; ++i) {
|
||||
boost::allocator_construct(a, p + i);
|
||||
}
|
||||
d.size() = 0;
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
inline void
|
||||
allocator_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> d(a, p);
|
||||
for (std::size_t& i = d.size(); i < n; ++i) {
|
||||
boost::allocator_construct(a, p + i, l[i % m]);
|
||||
}
|
||||
d.size() = 0;
|
||||
}
|
||||
|
||||
template<class A, class T, class I>
|
||||
inline void
|
||||
allocator_construct_n(A& a, T* p, std::size_t n, I b)
|
||||
{
|
||||
detail::alloc_destroyer<A, T> d(a, p);
|
||||
for (std::size_t& i = d.size(); i < n; void(++i), void(++b)) {
|
||||
boost::allocator_construct(a, p + i, *b);
|
||||
}
|
||||
d.size() = 0;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
template<class A>
|
||||
using allocator_value_type_t = typename allocator_value_type<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_pointer_t = typename allocator_pointer<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_const_pointer_t = typename allocator_const_pointer<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_void_pointer_t = typename allocator_void_pointer<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_const_void_pointer_t =
|
||||
typename allocator_const_void_pointer<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_difference_type_t =
|
||||
typename allocator_difference_type<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_size_type_t = typename allocator_size_type<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_propagate_on_container_copy_assignment_t =
|
||||
typename allocator_propagate_on_container_copy_assignment<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_propagate_on_container_move_assignment_t =
|
||||
typename allocator_propagate_on_container_move_assignment<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_propagate_on_container_swap_t =
|
||||
typename allocator_propagate_on_container_swap<A>::type;
|
||||
|
||||
template<class A>
|
||||
using allocator_is_always_equal_t =
|
||||
typename allocator_is_always_equal<A>::type;
|
||||
|
||||
template<class A, class T>
|
||||
using allocator_rebind_t = typename allocator_rebind<A, T>::type;
|
||||
#endif
|
||||
|
||||
} /* boost */
|
||||
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wdeprecated-declarations")
|
||||
# pragma clang diagnostic pop
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#elif defined(BOOST_GCC) && BOOST_GCC >= 40600
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
#if defined(_STL_RESTORE_DEPRECATED_WARNING)
|
||||
_STL_RESTORE_DEPRECATED_WARNING
|
||||
#endif
|
||||
#if defined(_LIBCPP_SUPPRESS_DEPRECATED_POP)
|
||||
_LIBCPP_SUPPRESS_DEPRECATED_POP
|
||||
#endif
|
||||
|
||||
#endif
|
112
include/boost/core/allocator_traits.hpp
Normal file
112
include/boost/core/allocator_traits.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
Copyright 2021 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_CORE_ALLOCATOR_TRAITS_HPP
|
||||
#define BOOST_CORE_ALLOCATOR_TRAITS_HPP
|
||||
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class A>
|
||||
struct allocator_traits {
|
||||
typedef A allocator_type;
|
||||
|
||||
typedef typename allocator_value_type<A>::type value_type;
|
||||
|
||||
typedef typename allocator_pointer<A>::type pointer;
|
||||
|
||||
typedef typename allocator_const_pointer<A>::type const_pointer;
|
||||
|
||||
typedef typename allocator_void_pointer<A>::type void_pointer;
|
||||
|
||||
typedef typename allocator_const_void_pointer<A>::type const_void_pointer;
|
||||
|
||||
typedef typename allocator_difference_type<A>::type difference_type;
|
||||
|
||||
typedef typename allocator_size_type<A>::type size_type;
|
||||
|
||||
typedef typename allocator_propagate_on_container_copy_assignment<A>::type
|
||||
propagate_on_container_copy_assignment;
|
||||
|
||||
typedef typename allocator_propagate_on_container_move_assignment<A>::type
|
||||
propagate_on_container_move_assignment;
|
||||
|
||||
typedef typename allocator_propagate_on_container_swap<A>::type
|
||||
propagate_on_container_swap;
|
||||
|
||||
typedef typename allocator_is_always_equal<A>::type is_always_equal;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
template<class T>
|
||||
using rebind_traits = allocator_traits<typename
|
||||
allocator_rebind<A, T>::type>;
|
||||
#else
|
||||
template<class T>
|
||||
struct rebind_traits
|
||||
: allocator_traits<typename allocator_rebind<A, T>::type> { };
|
||||
#endif
|
||||
|
||||
static pointer allocate(A& a, size_type n) {
|
||||
return boost::allocator_allocate(a, n);
|
||||
}
|
||||
|
||||
static pointer allocate(A& a, size_type n, const_void_pointer h) {
|
||||
return boost::allocator_allocate(a, n, h);
|
||||
}
|
||||
|
||||
static void deallocate(A& a, pointer p, size_type n) {
|
||||
return boost::allocator_deallocate(a, p, n);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void construct(A& a, T* p) {
|
||||
boost::allocator_construct(a, p);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class T, class V, class... Args>
|
||||
static void construct(A& a, T* p, V&& v, Args&&... args) {
|
||||
boost::allocator_construct(a, p, std::forward<V>(v),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
template<class T, class V>
|
||||
static void construct(A& a, T* p, V&& v) {
|
||||
boost::allocator_construct(a, p, std::forward<V>(v));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
template<class T, class V>
|
||||
static void construct(A& a, T* p, const V& v) {
|
||||
boost::allocator_construct(a, p, v);
|
||||
}
|
||||
|
||||
template<class T, class V>
|
||||
static void construct(A& a, T* p, V& v) {
|
||||
boost::allocator_construct(a, p, v);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
static void destroy(A& a, T* p) {
|
||||
boost::allocator_destroy(a, p);
|
||||
}
|
||||
|
||||
static size_type max_size(const A& a) BOOST_NOEXCEPT {
|
||||
return boost::allocator_max_size(a);
|
||||
}
|
||||
|
||||
static A select_on_container_copy_construction(const A& a) {
|
||||
return boost::allocator_select_on_container_copy_construction(a);
|
||||
}
|
||||
};
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
954
include/boost/core/bit.hpp
Normal file
954
include/boost/core/bit.hpp
Normal file
@ -0,0 +1,954 @@
|
||||
#ifndef BOOST_CORE_BIT_HPP_INCLUDED
|
||||
#define BOOST_CORE_BIT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/core/bit.hpp
|
||||
//
|
||||
// A portable version of the C++20 standard header <bit>
|
||||
//
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <limits>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
# include <intrin.h>
|
||||
# pragma intrinsic(_BitScanForward)
|
||||
# pragma intrinsic(_BitScanReverse)
|
||||
|
||||
# if defined(_M_X64) || defined(_M_ARM64)
|
||||
# pragma intrinsic(_BitScanForward64)
|
||||
# pragma intrinsic(_BitScanReverse64)
|
||||
# endif
|
||||
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
# pragma warning(disable: 4244) // conversion from int to T
|
||||
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC >= 1925
|
||||
# define BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL
|
||||
#endif
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__builtin_bit_cast)
|
||||
# define BOOST_CORE_HAS_BUILTIN_BIT_CAST
|
||||
# endif
|
||||
# if __has_builtin(__builtin_bswap16)
|
||||
# define BOOST_CORE_HAS_BUILTIN_BSWAP16
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_CORE_HAS_BUILTIN_BIT_CAST) && (defined(BOOST_MSVC) && BOOST_MSVC >= 1926)
|
||||
# define BOOST_CORE_HAS_BUILTIN_BIT_CAST
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_CORE_HAS_BUILTIN_BSWAP16) && (defined(BOOST_GCC) && BOOST_GCC >= 40800)
|
||||
# define BOOST_CORE_HAS_BUILTIN_BSWAP16
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
// bit_cast
|
||||
|
||||
#if defined(BOOST_CORE_HAS_BUILTIN_BIT_CAST)
|
||||
|
||||
template<class To, class From>
|
||||
BOOST_CONSTEXPR To bit_cast( From const & from ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_bit_cast( To, from );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class To, class From>
|
||||
To bit_cast( From const & from ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( sizeof(To) == sizeof(From) );
|
||||
|
||||
To to;
|
||||
std::memcpy( &to, &from, sizeof(To) );
|
||||
return to;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// countl
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( unsigned char x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clz( x ) - ( std::numeric_limits<unsigned int>::digits - std::numeric_limits<unsigned char>::digits ): std::numeric_limits<unsigned char>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( unsigned short x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clz( x ) - ( std::numeric_limits<unsigned int>::digits - std::numeric_limits<unsigned short>::digits ): std::numeric_limits<unsigned short>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( unsigned int x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clz( x ): std::numeric_limits<unsigned int>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( unsigned long x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clzl( x ): std::numeric_limits<unsigned long>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
return boost::core::detail::countl_impl( x );
|
||||
}
|
||||
|
||||
#else // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( __builtin_is_constant_evaluated() )
|
||||
{
|
||||
constexpr unsigned char mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 };
|
||||
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
|
||||
return mod37[ x % 37 ];
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long r;
|
||||
|
||||
if( _BitScanReverse( &r, x ) )
|
||||
{
|
||||
return 31 - static_cast<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned long r;
|
||||
|
||||
if( _BitScanReverse( &r, x ) )
|
||||
{
|
||||
return 31 - static_cast<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
|
||||
inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
|
||||
}
|
||||
|
||||
inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
static unsigned char const mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 };
|
||||
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
|
||||
return mod37[ x % 37 ];
|
||||
}
|
||||
|
||||
inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
|
||||
}
|
||||
|
||||
inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( __builtin_is_constant_evaluated() )
|
||||
{
|
||||
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
|
||||
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
|
||||
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long r;
|
||||
|
||||
if( _BitScanReverse64( &r, x ) )
|
||||
{
|
||||
return 63 - static_cast<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
|
||||
|
||||
inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned long r;
|
||||
|
||||
if( _BitScanReverse64( &r, x ) )
|
||||
{
|
||||
return 63 - static_cast<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
|
||||
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
|
||||
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
|
||||
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
|
||||
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
BOOST_CXX14_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
|
||||
|
||||
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint8_t>( x ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint16_t>( x ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint64_t>( x ) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
return boost::core::countl_zero( static_cast<T>( ~x ) );
|
||||
}
|
||||
|
||||
// countr
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( unsigned char x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctz( x ): std::numeric_limits<unsigned char>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( unsigned short x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctz( x ): std::numeric_limits<unsigned short>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( unsigned int x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctz( x ): std::numeric_limits<unsigned int>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( unsigned long x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctzl( x ): std::numeric_limits<unsigned long>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
return boost::core::detail::countr_impl( x );
|
||||
}
|
||||
|
||||
#else // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( __builtin_is_constant_evaluated() )
|
||||
{
|
||||
constexpr unsigned char mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 };
|
||||
return mod37[ ( -(boost::int32_t)x & x ) % 37 ];
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long r;
|
||||
|
||||
if( _BitScanForward( &r, x ) )
|
||||
{
|
||||
return static_cast<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned long r;
|
||||
|
||||
if( _BitScanForward( &r, x ) )
|
||||
{
|
||||
return static_cast<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
|
||||
inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
|
||||
}
|
||||
|
||||
inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
static unsigned char const mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 };
|
||||
return mod37[ ( -(boost::int32_t)x & x ) % 37 ];
|
||||
}
|
||||
|
||||
inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
|
||||
}
|
||||
|
||||
inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( __builtin_is_constant_evaluated() )
|
||||
{
|
||||
return static_cast<boost::uint32_t>( x ) != 0?
|
||||
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
|
||||
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long r;
|
||||
|
||||
if( _BitScanForward64( &r, x ) )
|
||||
{
|
||||
return static_cast<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
|
||||
|
||||
inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned long r;
|
||||
|
||||
if( _BitScanForward64( &r, x ) )
|
||||
{
|
||||
return static_cast<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<boost::uint32_t>( x ) != 0?
|
||||
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
|
||||
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<boost::uint32_t>( x ) != 0?
|
||||
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
|
||||
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
BOOST_CXX14_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
|
||||
|
||||
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint8_t>( x ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint16_t>( x ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint64_t>( x ) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
return boost::core::countr_zero( static_cast<T>( ~x ) );
|
||||
}
|
||||
|
||||
// popcount
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
#if defined(__clang__) && __clang_major__ * 100 + __clang_minor__ < 304
|
||||
# define BOOST_CORE_POPCOUNT_CONSTEXPR
|
||||
#else
|
||||
# define BOOST_CORE_POPCOUNT_CONSTEXPR BOOST_CONSTEXPR
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned char x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_popcount( x );
|
||||
}
|
||||
|
||||
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned short x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_popcount( x );
|
||||
}
|
||||
|
||||
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned int x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_popcount( x );
|
||||
}
|
||||
|
||||
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_popcountl( x );
|
||||
}
|
||||
|
||||
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_popcountll( x );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#undef BOOST_CORE_POPCOUNT_CONSTEXPR
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
return boost::core::detail::popcount_impl( x );
|
||||
}
|
||||
|
||||
#else // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
x = x - ( ( x >> 1 ) & 0x55555555 );
|
||||
x = ( x & 0x33333333 ) + ( ( x >> 2 ) & 0x33333333 );
|
||||
x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F;
|
||||
|
||||
return static_cast<unsigned>( ( x * 0x01010101 ) >> 24 );
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
x = x - ( ( x >> 1 ) & 0x5555555555555555 );
|
||||
x = ( x & 0x3333333333333333 ) + ( ( x >> 2 ) & 0x3333333333333333 );
|
||||
x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F0F0F0F0F;
|
||||
|
||||
return static_cast<unsigned>( ( x * 0x0101010101010101 ) >> 56 );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
|
||||
|
||||
BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
|
||||
{
|
||||
return boost::core::detail::popcount_impl( static_cast<boost::uint32_t>( x ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::core::detail::popcount_impl( static_cast<boost::uint64_t>( x ) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
// rotating
|
||||
|
||||
template<class T>
|
||||
BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
unsigned const mask = std::numeric_limits<T>::digits - 1;
|
||||
return static_cast<T>( x << (static_cast<unsigned>( s ) & mask) | x >> (static_cast<unsigned>( -s ) & mask) );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
unsigned const mask = std::numeric_limits<T>::digits - 1;
|
||||
return static_cast<T>( x >> (static_cast<unsigned>( s ) & mask) | x << (static_cast<unsigned>( -s ) & mask) );
|
||||
}
|
||||
|
||||
// integral powers of 2
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
return x != 0 && ( x & ( x - 1 ) ) == 0;
|
||||
}
|
||||
|
||||
// bit_width returns `int` now, https://cplusplus.github.io/LWG/issue3656
|
||||
// has been applied to C++20 as a DR
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR int bit_width( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
return std::numeric_limits<T>::digits - boost::core::countl_zero( x );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
return x == 0? T(0): static_cast<T>( T(1) << ( boost::core::bit_width( x ) - 1 ) );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint32_t bit_ceil_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( x == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
--x;
|
||||
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
|
||||
++x;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( x == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
--x;
|
||||
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
x |= x >> 32;
|
||||
|
||||
++x;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
|
||||
|
||||
BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint32_t>( x ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint64_t>( x ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// endian
|
||||
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
|
||||
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
|
||||
|
||||
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
|
||||
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big
|
||||
|
||||
#elif defined(__BYTE_ORDER__) && defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
|
||||
|
||||
# define BOOST_CORE_BIT_NATIVE_INITIALIZER
|
||||
|
||||
#elif defined(__LITTLE_ENDIAN__)
|
||||
|
||||
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
|
||||
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
|
||||
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big
|
||||
|
||||
#elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_CORE_BIT_NATIVE_INITIALIZER
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
|
||||
enum class endian
|
||||
{
|
||||
big,
|
||||
little,
|
||||
native BOOST_CORE_BIT_NATIVE_INITIALIZER
|
||||
};
|
||||
|
||||
typedef endian endian_type;
|
||||
|
||||
#else
|
||||
|
||||
namespace endian
|
||||
{
|
||||
|
||||
enum type
|
||||
{
|
||||
big,
|
||||
little,
|
||||
native BOOST_CORE_BIT_NATIVE_INITIALIZER
|
||||
};
|
||||
|
||||
} // namespace endian
|
||||
|
||||
typedef endian::type endian_type;
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_CORE_BIT_NATIVE_INITIALIZER
|
||||
|
||||
// byteswap
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
BOOST_CONSTEXPR inline boost::uint8_t byteswap_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
#if defined(BOOST_CORE_HAS_BUILTIN_BSWAP16)
|
||||
|
||||
BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_bswap16( x );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<boost::uint16_t>( x << 8 | x >> 8 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_bswap32( x );
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_bswap64( x );
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( __builtin_is_constant_evaluated() )
|
||||
{
|
||||
boost::uint32_t step16 = x << 16 | x >> 16;
|
||||
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _byteswap_ulong( x );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( __builtin_is_constant_evaluated() )
|
||||
{
|
||||
boost::uint64_t step32 = x << 32 | x >> 32;
|
||||
boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
|
||||
return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _byteswap_uint64( x );
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return _byteswap_ulong( x );
|
||||
}
|
||||
|
||||
inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return _byteswap_uint64( x );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::uint32_t step16 = x << 16 | x >> 16;
|
||||
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::uint64_t step32 = x << 32 | x >> 32;
|
||||
boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
|
||||
return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T> BOOST_CXX14_CONSTEXPR T byteswap( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
|
||||
|
||||
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint8_t>( x ) ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint16_t>( x ) ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint32_t>( x ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint64_t>( x ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_CORE_BIT_HPP_INCLUDED
|
@ -30,19 +30,40 @@ namespace boost
|
||||
|
||||
template<class T> inline void checked_delete(T * x) BOOST_NOEXCEPT
|
||||
{
|
||||
// intentionally complex - simplification causes regressions
|
||||
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
|
||||
#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410L
|
||||
|
||||
static_assert( sizeof(T) != 0, "Type must be complete" );
|
||||
|
||||
#else
|
||||
|
||||
typedef char type_must_be_complete[ sizeof(T) ];
|
||||
(void) sizeof(type_must_be_complete);
|
||||
|
||||
#endif
|
||||
|
||||
delete x;
|
||||
}
|
||||
|
||||
template<class T> inline void checked_array_delete(T * x) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
|
||||
#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410L
|
||||
|
||||
static_assert( sizeof(T) != 0, "Type must be complete" );
|
||||
|
||||
#else
|
||||
|
||||
typedef char type_must_be_complete[ sizeof(T) ];
|
||||
(void) sizeof(type_must_be_complete);
|
||||
|
||||
#endif
|
||||
|
||||
delete [] x;
|
||||
}
|
||||
|
||||
// Block unintended ADL
|
||||
namespace checked_deleters
|
||||
{
|
||||
|
||||
template<class T> struct checked_deleter
|
||||
{
|
||||
typedef void result_type;
|
||||
@ -66,6 +87,11 @@ template<class T> struct checked_array_deleter
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace checked_deleters
|
||||
|
||||
using checked_deleters::checked_deleter;
|
||||
using checked_deleters::checked_array_deleter;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_CHECKED_DELETE_HPP
|
||||
|
298
include/boost/core/cmath.hpp
Normal file
298
include/boost/core/cmath.hpp
Normal file
@ -0,0 +1,298 @@
|
||||
#ifndef BOOST_CORE_CMATH_HPP_INCLUDED
|
||||
#define BOOST_CORE_CMATH_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/core/cmath.hpp
|
||||
//
|
||||
// Floating point classification and sign manipulation functions
|
||||
// Extracted from https://github.com/boostorg/lexical_cast/pull/37
|
||||
//
|
||||
// Copyright 2020, 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#if defined(BOOST_CORE_USE_GENERIC_CMATH) || (!defined(_MSC_VER) && !defined(FP_SUBNORMAL))
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <limits>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
// fpclassify return values
|
||||
|
||||
int const fp_zero = 0;
|
||||
int const fp_subnormal = 1;
|
||||
int const fp_normal = 2;
|
||||
int const fp_infinite = 3;
|
||||
int const fp_nan = 4;
|
||||
|
||||
// Classification functions
|
||||
|
||||
template<class T> bool isfinite( T x )
|
||||
{
|
||||
return x <= (std::numeric_limits<T>::max)() && x >= -(std::numeric_limits<T>::max)();
|
||||
}
|
||||
|
||||
template<class T> bool isinf( T x )
|
||||
{
|
||||
return x > (std::numeric_limits<T>::max)() || x < -(std::numeric_limits<T>::max)();
|
||||
}
|
||||
|
||||
template<class T> bool isnan( T x )
|
||||
{
|
||||
return !isfinite( x ) && !isinf( x );
|
||||
}
|
||||
|
||||
template<class T> bool isnormal( T x )
|
||||
{
|
||||
return isfinite( x ) && ( x >= (std::numeric_limits<T>::min)() || x <= -(std::numeric_limits<T>::min)() );
|
||||
}
|
||||
|
||||
template<class T> int fpclassify( T x )
|
||||
{
|
||||
if( x == 0 ) return fp_zero;
|
||||
|
||||
if( x < 0 ) x = -x;
|
||||
|
||||
if( x > (std::numeric_limits<T>::max)() ) return fp_infinite;
|
||||
|
||||
if( x >= (std::numeric_limits<T>::min)() ) return fp_normal;
|
||||
|
||||
if( x < (std::numeric_limits<T>::min)() ) return fp_subnormal;
|
||||
|
||||
return fp_nan;
|
||||
}
|
||||
|
||||
// Sign manipulation functions
|
||||
|
||||
inline bool signbit( float x )
|
||||
{
|
||||
boost::int32_t y;
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
|
||||
|
||||
std::memcpy( &y, &x, sizeof( y ) );
|
||||
|
||||
return y < 0;
|
||||
}
|
||||
|
||||
inline bool signbit( double x )
|
||||
{
|
||||
boost::int64_t y;
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
|
||||
|
||||
std::memcpy( &y, &x, sizeof( y ) );
|
||||
|
||||
return y < 0;
|
||||
}
|
||||
|
||||
inline bool signbit( long double x )
|
||||
{
|
||||
return signbit( static_cast<double>( x ) );
|
||||
}
|
||||
|
||||
template<class T> T copysign( T x, T y )
|
||||
{
|
||||
return signbit( x ) == signbit( y )? x: -x;
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#else // defined(BOOST_CORE_USE_GENERIC_CMATH)
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
# include <float.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
|
||||
template<class T> T copysign( T x, T y )
|
||||
{
|
||||
return static_cast<T>( _copysign( static_cast<double>( x ), static_cast<double>( y ) ) );
|
||||
}
|
||||
|
||||
template<class T> bool isnan( T x )
|
||||
{
|
||||
return _isnan( static_cast<double>( x ) ) != 0;
|
||||
}
|
||||
|
||||
template<class T> bool isfinite( T x )
|
||||
{
|
||||
return _finite( static_cast<double>( x ) ) != 0;
|
||||
}
|
||||
|
||||
template<class T> bool isinf( T x )
|
||||
{
|
||||
return ( _fpclass( static_cast<double>( x ) ) & ( _FPCLASS_PINF | _FPCLASS_NINF ) ) != 0;
|
||||
}
|
||||
|
||||
inline bool isnormal( float x )
|
||||
{
|
||||
// no _fpclassf in 32 bit mode
|
||||
unsigned y = reinterpret_cast< unsigned const& >( x );
|
||||
unsigned exp = ( y >> 23 ) & 0xFF;
|
||||
return exp != 0 && exp != 0xFF;
|
||||
}
|
||||
|
||||
inline bool isnormal( double x )
|
||||
{
|
||||
return ( _fpclass( x ) & ( _FPCLASS_PN | _FPCLASS_NN ) ) != 0;
|
||||
}
|
||||
|
||||
inline bool isnormal( long double x )
|
||||
{
|
||||
return boost::core::isnormal( static_cast<double>( x ) );
|
||||
}
|
||||
|
||||
template<class T> bool signbit( T x )
|
||||
{
|
||||
return _copysign( 1.0, static_cast<double>( x ) ) < 0.0;
|
||||
}
|
||||
|
||||
int const fp_zero = 0;
|
||||
int const fp_subnormal = 1;
|
||||
int const fp_normal = 2;
|
||||
int const fp_infinite = 3;
|
||||
int const fp_nan = 4;
|
||||
|
||||
inline int fpclassify( float x )
|
||||
{
|
||||
switch( _fpclass( x ) )
|
||||
{
|
||||
case _FPCLASS_SNAN:
|
||||
case _FPCLASS_QNAN:
|
||||
|
||||
return fp_nan;
|
||||
|
||||
case _FPCLASS_NINF:
|
||||
case _FPCLASS_PINF:
|
||||
|
||||
return fp_infinite;
|
||||
|
||||
case _FPCLASS_NZ:
|
||||
case _FPCLASS_PZ:
|
||||
|
||||
return fp_zero;
|
||||
|
||||
default:
|
||||
|
||||
return boost::core::isnormal( x )? fp_normal: fp_subnormal;
|
||||
}
|
||||
}
|
||||
|
||||
inline int fpclassify( double x )
|
||||
{
|
||||
switch( _fpclass( x ) )
|
||||
{
|
||||
case _FPCLASS_SNAN:
|
||||
case _FPCLASS_QNAN:
|
||||
|
||||
return fp_nan;
|
||||
|
||||
case _FPCLASS_NINF:
|
||||
case _FPCLASS_PINF:
|
||||
|
||||
return fp_infinite;
|
||||
|
||||
case _FPCLASS_NZ:
|
||||
case _FPCLASS_PZ:
|
||||
|
||||
return fp_zero;
|
||||
|
||||
case _FPCLASS_ND:
|
||||
case _FPCLASS_PD:
|
||||
|
||||
return fp_subnormal;
|
||||
|
||||
default:
|
||||
|
||||
return fp_normal;
|
||||
}
|
||||
}
|
||||
|
||||
inline int fpclassify( long double x )
|
||||
{
|
||||
return boost::core::fpclassify( static_cast<double>( x ) );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
using std::isfinite;
|
||||
using std::isnan;
|
||||
using std::isinf;
|
||||
using std::isnormal;
|
||||
using std::fpclassify;
|
||||
|
||||
int const fp_zero = FP_ZERO;
|
||||
int const fp_subnormal = FP_SUBNORMAL;
|
||||
int const fp_normal = FP_NORMAL;
|
||||
int const fp_infinite = FP_INFINITE;
|
||||
int const fp_nan = FP_NAN;
|
||||
|
||||
using std::signbit;
|
||||
|
||||
// std::copysign doesn't exist in libstdc++ under -std=c++03
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
|
||||
template<class T> T copysign( T x, T y )
|
||||
{
|
||||
return std::copysign( x, y );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// ::copysignl is unreliable, use the built-ins
|
||||
|
||||
inline float copysign_impl( float x, float y )
|
||||
{
|
||||
return __builtin_copysignf( x, y );
|
||||
}
|
||||
|
||||
inline double copysign_impl( double x, double y )
|
||||
{
|
||||
return __builtin_copysign( x, y );
|
||||
}
|
||||
|
||||
inline long double copysign_impl( long double x, long double y )
|
||||
{
|
||||
return __builtin_copysignl( x, y );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T> T copysign( T x, T y )
|
||||
{
|
||||
return boost::core::detail::copysign_impl( x, y );
|
||||
}
|
||||
|
||||
#endif // !defined(__GNUC__)
|
||||
#endif // #if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // defined(BOOST_CORE_USE_GENERIC_CMATH)
|
||||
|
||||
#endif // #ifndef BOOST_CORE_CMATH_HPP_INCLUDED
|
46
include/boost/core/data.hpp
Normal file
46
include/boost/core/data.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_CORE_DATA_HPP
|
||||
#define BOOST_CORE_DATA_HPP
|
||||
|
||||
#include <initializer_list>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class C>
|
||||
inline constexpr auto
|
||||
data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data())
|
||||
{
|
||||
return c.data();
|
||||
}
|
||||
|
||||
template<class C>
|
||||
inline constexpr auto
|
||||
data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data())
|
||||
{
|
||||
return c.data();
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline constexpr T*
|
||||
data(T(&a)[N]) noexcept
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline constexpr const T*
|
||||
data(std::initializer_list<T> l) noexcept
|
||||
{
|
||||
return l.begin();
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
@ -10,11 +10,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <new>
|
||||
#include <climits>
|
||||
|
||||
#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000
|
||||
#define BOOST_CORE_NO_CXX11_ALLOCATOR
|
||||
#endif
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@ -24,21 +20,25 @@ BOOST_NORETURN void throw_exception(const std::exception&);
|
||||
|
||||
namespace default_ {
|
||||
|
||||
struct true_type {
|
||||
template<bool V>
|
||||
struct bool_constant {
|
||||
typedef bool value_type;
|
||||
typedef true_type type;
|
||||
typedef bool_constant type;
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
static const bool value = V;
|
||||
|
||||
BOOST_CONSTEXPR operator bool() const BOOST_NOEXCEPT {
|
||||
return true;
|
||||
operator bool() const BOOST_NOEXCEPT {
|
||||
return V;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR bool operator()() const BOOST_NOEXCEPT {
|
||||
return true;
|
||||
bool operator()() const BOOST_NOEXCEPT {
|
||||
return V;
|
||||
}
|
||||
};
|
||||
|
||||
template<bool V>
|
||||
const bool bool_constant<V>::value;
|
||||
|
||||
template<class T>
|
||||
struct add_reference {
|
||||
typedef T& type;
|
||||
@ -63,8 +63,8 @@ struct default_allocator {
|
||||
typedef typename add_reference<const T>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef true_type propagate_on_container_move_assignment;
|
||||
typedef true_type is_always_equal;
|
||||
typedef bool_constant<true> propagate_on_container_move_assignment;
|
||||
typedef bool_constant<true> is_always_equal;
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
@ -81,16 +81,9 @@ struct default_allocator {
|
||||
BOOST_CONSTEXPR default_allocator(const default_allocator<U>&)
|
||||
BOOST_NOEXCEPT { }
|
||||
|
||||
#if defined(PTRDIFF_MAX) && defined(SIZE_MAX)
|
||||
BOOST_CONSTEXPR std::size_t max_size() const BOOST_NOEXCEPT {
|
||||
return PTRDIFF_MAX < SIZE_MAX / sizeof(T)
|
||||
? PTRDIFF_MAX : SIZE_MAX / sizeof(T);
|
||||
return static_cast<std::size_t>(-1) / (2 < sizeof(T) ? sizeof(T) : 2);
|
||||
}
|
||||
#else
|
||||
BOOST_CONSTEXPR std::size_t max_size() const BOOST_NOEXCEPT {
|
||||
return ~static_cast<std::size_t>(0) / sizeof(T);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
T* allocate(std::size_t n) {
|
||||
@ -120,7 +113,14 @@ struct default_allocator {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_CORE_NO_CXX11_ALLOCATOR)
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
T* allocate(std::size_t n, const void*) {
|
||||
return allocate(n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000) || \
|
||||
defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class U, class V>
|
||||
void construct(U* p, const V& v) {
|
||||
::new(p) U(v);
|
||||
@ -129,6 +129,7 @@ struct default_allocator {
|
||||
template<class U>
|
||||
void destroy(U* p) {
|
||||
p->~U();
|
||||
(void)p;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#if defined( BOOST_CORE_HAS_CXXABI_H )
|
||||
# include <cxxabi.h>
|
||||
// For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
|
||||
// For some architectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
|
||||
// (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement
|
||||
// abi::__cxa_demangle(). We detect this implementation by checking the include guard here.
|
||||
# if defined( __GABIXX_CXXABI_H__ )
|
||||
|
18
include/boost/core/detail/assert.hpp
Normal file
18
include/boost/core/detail/assert.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright 2025 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#undef BOOST_CORE_DETAIL_ASSERT
|
||||
|
||||
#if !defined(__clang__) && \
|
||||
!defined(__INTEL_COMPILER) && \
|
||||
defined(__GNUC__) && \
|
||||
(__GNUC__ < 5)
|
||||
#define BOOST_CORE_DETAIL_ASSERT(expr) void(0)
|
||||
#else
|
||||
#include <boost/assert.hpp>
|
||||
#define BOOST_CORE_DETAIL_ASSERT(expr) BOOST_ASSERT(expr)
|
||||
#endif
|
39
include/boost/core/detail/is_same.hpp
Normal file
39
include/boost/core/detail/is_same.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef BOOST_CORE_DETAIL_IS_SAME_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_IS_SAME_HPP_INCLUDED
|
||||
|
||||
// is_same<T1,T2>::value is true when T1 == T2
|
||||
//
|
||||
// Copyright 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the 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 <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< class T1, class T2 > struct is_same
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = false );
|
||||
};
|
||||
|
||||
template< class T > struct is_same< T, T >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = true );
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_IS_SAME_HPP_INCLUDED
|
66
include/boost/core/detail/lwt_unattended.hpp
Normal file
66
include/boost/core/detail/lwt_unattended.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef BOOST_CORE_DETAIL_LWT_UNATTENDED_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_LWT_UNATTENDED_HPP_INCLUDED
|
||||
|
||||
// Copyright 2014, 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <cstdlib>
|
||||
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
|
||||
# include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Setup unattended mode by disabling interactive popups on
|
||||
// assertion failures
|
||||
|
||||
inline void lwt_unattended()
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER > 1310)
|
||||
|
||||
// disable message boxes on assert(), abort()
|
||||
::_set_abort_behavior( 0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT );
|
||||
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4996)
|
||||
|
||||
# if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
# endif
|
||||
|
||||
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY == 100 /*WINAPI_FAMILY_DESKTOP_APP*/
|
||||
|
||||
// disable message box on crash
|
||||
::_seterrormode( /*SEM_NOGPFAULTERRORBOX*/ 0x0002 );
|
||||
|
||||
#endif
|
||||
|
||||
# if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
# endif
|
||||
|
||||
# pragma warning(pop)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
|
||||
|
||||
// disable message boxes on iterator debugging violations
|
||||
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_LWT_UNATTENDED_HPP_INCLUDED
|
58
include/boost/core/detail/minstd_rand.hpp
Normal file
58
include/boost/core/detail/minstd_rand.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef BOOST_CORE_DETAIL_MINSTD_RAND_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_MINSTD_RAND_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// An implementation of minstd_rand that does not require
|
||||
// the Random library
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class minstd_rand
|
||||
{
|
||||
private:
|
||||
|
||||
boost::uint_least32_t x_;
|
||||
|
||||
enum { a = 48271, m = 2147483647 };
|
||||
|
||||
public:
|
||||
|
||||
minstd_rand(): x_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
explicit minstd_rand( boost::uint_least32_t x ): x_( x % m )
|
||||
{
|
||||
if( x_ == 0 )
|
||||
{
|
||||
x_ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
boost::uint_least32_t operator()()
|
||||
{
|
||||
boost::uint_least64_t y = x_;
|
||||
|
||||
y = ( a * y ) % m;
|
||||
|
||||
x_ = static_cast<boost::uint_least32_t>( y );
|
||||
|
||||
return x_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_MINSTD_RAND_HPP_INCLUDED
|
71
include/boost/core/detail/sp_thread_pause.hpp
Normal file
71
include/boost/core/detail/sp_thread_pause.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/core/detail/sp_thread_pause.hpp
|
||||
//
|
||||
// inline void bost::core::sp_thread_pause();
|
||||
//
|
||||
// Emits a "pause" instruction.
|
||||
//
|
||||
// Copyright 2008, 2020, 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__builtin_ia32_pause) && !defined(__INTEL_COMPILER)
|
||||
# define BOOST_CORE_HAS_BUILTIN_IA32_PAUSE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_CORE_HAS_BUILTIN_IA32_PAUSE)
|
||||
|
||||
# define BOOST_CORE_SP_PAUSE() __builtin_ia32_pause()
|
||||
|
||||
#elif defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) )
|
||||
|
||||
# include <intrin.h>
|
||||
# define BOOST_CORE_SP_PAUSE() _mm_pause()
|
||||
|
||||
#elif defined(_MSC_VER) && ( defined(_M_ARM) || defined(_M_ARM64) )
|
||||
|
||||
# include <intrin.h>
|
||||
# define BOOST_CORE_SP_PAUSE() __yield()
|
||||
|
||||
#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
|
||||
|
||||
# define BOOST_CORE_SP_PAUSE() __asm__ __volatile__( "rep; nop" : : : "memory" )
|
||||
|
||||
#elif defined(__GNUC__) && ( (defined(__ARM_ARCH) && __ARM_ARCH >= 8) || defined(__ARM_ARCH_8A__) || defined(__aarch64__) )
|
||||
|
||||
# define BOOST_CORE_SP_PAUSE() __asm__ __volatile__( "yield" : : : "memory" )
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_CORE_SP_PAUSE() ((void)0)
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
BOOST_FORCEINLINE void sp_thread_pause() BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_CORE_SP_PAUSE();
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_CORE_SP_PAUSE
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED
|
122
include/boost/core/detail/sp_thread_sleep.hpp
Normal file
122
include/boost/core/detail/sp_thread_sleep.hpp
Normal file
@ -0,0 +1,122 @@
|
||||
#ifndef BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/core/detail/sp_thread_sleep.hpp
|
||||
//
|
||||
// inline void bost::core::sp_thread_sleep();
|
||||
//
|
||||
// Cease execution for a while to yield to other threads,
|
||||
// as if by calling nanosleep() with an appropriate interval.
|
||||
//
|
||||
// Copyright 2008, 2020, 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
BOOST_PRAGMA_MESSAGE("Using Sleep(1) in sp_thread_sleep")
|
||||
#endif
|
||||
|
||||
#include <boost/core/detail/sp_win32_sleep.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void sp_thread_sleep() BOOST_NOEXCEPT
|
||||
{
|
||||
Sleep( 1 );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
using boost::core::detail::sp_thread_sleep;
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#elif defined(BOOST_HAS_NANOSLEEP)
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
BOOST_PRAGMA_MESSAGE("Using nanosleep() in sp_thread_sleep")
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
inline void sp_thread_sleep() BOOST_NOEXCEPT
|
||||
{
|
||||
#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) && !defined(__OHOS__)
|
||||
|
||||
int oldst;
|
||||
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldst );
|
||||
|
||||
#endif
|
||||
|
||||
// g++ -Wextra warns on {} or {0}
|
||||
struct timespec rqtp = { 0, 0 };
|
||||
|
||||
// POSIX says that timespec has tv_sec and tv_nsec
|
||||
// But it doesn't guarantee order or placement
|
||||
|
||||
rqtp.tv_sec = 0;
|
||||
rqtp.tv_nsec = 1000;
|
||||
|
||||
nanosleep( &rqtp, 0 );
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) && !defined(__OHOS__)
|
||||
|
||||
pthread_setcancelstate( oldst, &oldst );
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
BOOST_PRAGMA_MESSAGE("Using sp_thread_yield() in sp_thread_sleep")
|
||||
#endif
|
||||
|
||||
#include <boost/core/detail/sp_thread_yield.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
inline void sp_thread_sleep() BOOST_NOEXCEPT
|
||||
{
|
||||
sp_thread_yield();
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED
|
100
include/boost/core/detail/sp_thread_yield.hpp
Normal file
100
include/boost/core/detail/sp_thread_yield.hpp
Normal file
@ -0,0 +1,100 @@
|
||||
#ifndef BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/core/detail/sp_thread_yield.hpp
|
||||
//
|
||||
// inline void bost::core::sp_thread_yield();
|
||||
//
|
||||
// Gives up the remainder of the time slice,
|
||||
// as if by calling sched_yield().
|
||||
//
|
||||
// Copyright 2008, 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
BOOST_PRAGMA_MESSAGE("Using SwitchToThread() in sp_thread_yield")
|
||||
#endif
|
||||
|
||||
#include <boost/core/detail/sp_win32_sleep.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void sp_thread_yield() BOOST_NOEXCEPT
|
||||
{
|
||||
SwitchToThread();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
using boost::core::detail::sp_thread_yield;
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#elif defined(BOOST_HAS_SCHED_YIELD)
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
BOOST_PRAGMA_MESSAGE("Using sched_yield() in sp_thread_yield")
|
||||
#endif
|
||||
|
||||
#ifndef _AIX
|
||||
# include <sched.h>
|
||||
#else
|
||||
// AIX's sched.h defines ::var which sometimes conflicts with Lambda's var
|
||||
extern "C" int sched_yield(void);
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
inline void sp_thread_yield() BOOST_NOEXCEPT
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
|
||||
BOOST_PRAGMA_MESSAGE("Using sp_thread_pause() in sp_thread_yield")
|
||||
#endif
|
||||
|
||||
#include <boost/core/detail/sp_thread_pause.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
inline void sp_thread_yield() BOOST_NOEXCEPT
|
||||
{
|
||||
sp_thread_pause();
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED
|
54
include/boost/core/detail/sp_win32_sleep.hpp
Normal file
54
include/boost/core/detail/sp_win32_sleep.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/core/detail/sp_win32_sleep.hpp
|
||||
//
|
||||
// Declares the Win32 Sleep() function.
|
||||
//
|
||||
// Copyright 2008, 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_USE_WINDOWS_H )
|
||||
|
||||
#if defined(__clang__) && defined(__x86_64__)
|
||||
// clang x64 warns that __stdcall is ignored
|
||||
# define BOOST_CORE_SP_STDCALL
|
||||
#else
|
||||
# define BOOST_CORE_SP_STDCALL __stdcall
|
||||
#endif
|
||||
|
||||
#if defined(__LP64__) // Cygwin 64
|
||||
extern "C" __declspec(dllimport) void BOOST_CORE_SP_STDCALL Sleep( unsigned int ms );
|
||||
#else
|
||||
extern "C" __declspec(dllimport) void BOOST_CORE_SP_STDCALL Sleep( unsigned long ms );
|
||||
#endif
|
||||
|
||||
extern "C" __declspec(dllimport) int BOOST_CORE_SP_STDCALL SwitchToThread();
|
||||
|
||||
#undef BOOST_CORE_SP_STDCALL
|
||||
|
||||
#endif // !defined( BOOST_USE_WINDOWS_H )
|
||||
|
||||
} // namespace detail
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED
|
54
include/boost/core/detail/splitmix64.hpp
Normal file
54
include/boost/core/detail/splitmix64.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef BOOST_CORE_DETAIL_SPLITMIX64_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_SPLITMIX64_HPP_INCLUDED
|
||||
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// An implementation of splitmix64 for testing purposes,
|
||||
// derived from Sebastiano Vigna's public domain implementation
|
||||
// http://xorshift.di.unimi.it/splitmix64.c
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class splitmix64
|
||||
{
|
||||
private:
|
||||
|
||||
boost::uint64_t x_;
|
||||
|
||||
public:
|
||||
|
||||
splitmix64(): x_( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
explicit splitmix64( boost::uint64_t seed ): x_( seed )
|
||||
{
|
||||
}
|
||||
|
||||
boost::uint64_t operator()()
|
||||
{
|
||||
x_ += ( boost::uint64_t(0x9e3779b9u) << 32 ) + 0x7f4a7c15u;
|
||||
|
||||
boost::uint64_t z = x_;
|
||||
|
||||
z ^= z >> 30;
|
||||
z *= ( boost::uint64_t(0xbf58476du) << 32 ) + 0x1ce4e5b9u;
|
||||
z ^= z >> 27;
|
||||
z *= ( boost::uint64_t(0x94d049bbu) << 32 ) + 0x133111ebu;
|
||||
z ^= z >> 31;
|
||||
|
||||
return z;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_SPLITMIX64_HPP_INCLUDED
|
1278
include/boost/core/detail/string_view.hpp
Normal file
1278
include/boost/core/detail/string_view.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,11 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4510)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
@ -51,37 +56,37 @@ public:
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
|
||||
empty_value() = default;
|
||||
#else
|
||||
empty_value() { }
|
||||
BOOST_CONSTEXPR empty_value() { }
|
||||
#endif
|
||||
|
||||
empty_value(boost::empty_init_t)
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t)
|
||||
: value_() { }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class... Args>
|
||||
explicit empty_value(boost::empty_init_t, Args&&... args)
|
||||
: value_(std::forward<Args>(args)...) { }
|
||||
template<class U, class... Args>
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args)
|
||||
: value_(std::forward<U>(value), std::forward<Args>(args)...) { }
|
||||
#else
|
||||
template<class U>
|
||||
empty_value(boost::empty_init_t, U&& value)
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value)
|
||||
: value_(std::forward<U>(value)) { }
|
||||
#endif
|
||||
#else
|
||||
template<class U>
|
||||
empty_value(boost::empty_init_t, const U& value)
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value)
|
||||
: value_(value) { }
|
||||
|
||||
template<class U>
|
||||
empty_value(boost::empty_init_t, U& value)
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value)
|
||||
: value_(value) { }
|
||||
#endif
|
||||
|
||||
const T& get() const BOOST_NOEXCEPT {
|
||||
BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT {
|
||||
return value_;
|
||||
}
|
||||
|
||||
T& get() BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR T& get() BOOST_NOEXCEPT {
|
||||
return value_;
|
||||
}
|
||||
|
||||
@ -90,46 +95,94 @@ private:
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
#if defined(BOOST_MSVC)
|
||||
/*
|
||||
This is a workaround to an MSVC bug when T is a nested class:
|
||||
https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
class empty_value_base
|
||||
: public T {
|
||||
public:
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
|
||||
empty_value_base() = default;
|
||||
#else
|
||||
BOOST_CONSTEXPR empty_value_base() { }
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class U, class... Args>
|
||||
BOOST_CONSTEXPR empty_value_base(U&& value, Args&&... args)
|
||||
: T(std::forward<U>(value), std::forward<Args>(args)...) { }
|
||||
#else
|
||||
template<class U>
|
||||
BOOST_CONSTEXPR empty_value_base(U&& value)
|
||||
: T(std::forward<U>(value)) { }
|
||||
#endif
|
||||
#else
|
||||
template<class U>
|
||||
BOOST_CONSTEXPR empty_value_base(const U& value)
|
||||
: T(value) { }
|
||||
|
||||
template<class U>
|
||||
BOOST_CONSTEXPR empty_value_base(U& value)
|
||||
: T(value) { }
|
||||
#endif
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
#endif
|
||||
|
||||
template<class T, unsigned N>
|
||||
class empty_value<T, N, true>
|
||||
#if defined(BOOST_MSVC)
|
||||
: detail::empty_value_base<T> {
|
||||
typedef detail::empty_value_base<T> empty_base_;
|
||||
#else
|
||||
: T {
|
||||
typedef T empty_base_;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
|
||||
empty_value() = default;
|
||||
#else
|
||||
empty_value() { }
|
||||
BOOST_CONSTEXPR empty_value() { }
|
||||
#endif
|
||||
|
||||
empty_value(boost::empty_init_t)
|
||||
: T() { }
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t)
|
||||
: empty_base_() { }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class... Args>
|
||||
explicit empty_value(boost::empty_init_t, Args&&... args)
|
||||
: T(std::forward<Args>(args)...) { }
|
||||
template<class U, class... Args>
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args)
|
||||
: empty_base_(std::forward<U>(value), std::forward<Args>(args)...) { }
|
||||
#else
|
||||
template<class U>
|
||||
empty_value(boost::empty_init_t, U&& value)
|
||||
: T(std::forward<U>(value)) { }
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value)
|
||||
: empty_base_(std::forward<U>(value)) { }
|
||||
#endif
|
||||
#else
|
||||
template<class U>
|
||||
empty_value(boost::empty_init_t, const U& value)
|
||||
: T(value) { }
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value)
|
||||
: empty_base_(value) { }
|
||||
|
||||
template<class U>
|
||||
empty_value(boost::empty_init_t, U& value)
|
||||
: T(value) { }
|
||||
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value)
|
||||
: empty_base_(value) { }
|
||||
#endif
|
||||
|
||||
const T& get() const BOOST_NOEXCEPT {
|
||||
BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& get() BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR T& get() BOOST_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
@ -139,6 +192,12 @@ public:
|
||||
|
||||
using empty_::empty_value;
|
||||
|
||||
BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t();
|
||||
|
||||
} /* boost */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
53
include/boost/core/fclose_deleter.hpp
Normal file
53
include/boost/core/fclose_deleter.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2022.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file fclose_deleter.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 21.09.2022
|
||||
*
|
||||
* This header contains an \c fclose_deleter implementation. This is a deleter
|
||||
* function object that invokes <tt>std::fclose</tt> on the passed pointer to
|
||||
* a <tt>std::FILE</tt> structure.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_CORE_FCLOSE_DELETER_HPP
|
||||
#define BOOST_CORE_FCLOSE_DELETER_HPP
|
||||
|
||||
#include <cstdio>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Block unintended ADL
|
||||
namespace fclose_deleter_ns {
|
||||
|
||||
//! A function object that closes a file
|
||||
struct fclose_deleter
|
||||
{
|
||||
//! Function object result type
|
||||
typedef void result_type;
|
||||
/*!
|
||||
* Closes the file handle
|
||||
*/
|
||||
void operator() (std::FILE* p) const BOOST_NOEXCEPT
|
||||
{
|
||||
if (BOOST_LIKELY(!!p))
|
||||
std::fclose(p);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace fclose_deleter_ns
|
||||
|
||||
using fclose_deleter_ns::fclose_deleter;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_CORE_FCLOSE_DELETER_HPP
|
41
include/boost/core/functor.hpp
Normal file
41
include/boost/core/functor.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2024.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file functor.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 2024-01-23
|
||||
*
|
||||
* This header contains a \c functor implementation. This is a function object
|
||||
* that invokes a function that is specified as its template parameter.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_CORE_FUNCTOR_HPP
|
||||
#define BOOST_CORE_FUNCTOR_HPP
|
||||
|
||||
namespace boost::core {
|
||||
|
||||
// Block unintended ADL
|
||||
namespace functor_ns {
|
||||
|
||||
//! A function object that invokes a function specified as its template parameter
|
||||
template< auto Function >
|
||||
struct functor
|
||||
{
|
||||
template< typename... Args >
|
||||
auto operator() (Args&&... args) const noexcept(noexcept(Function(static_cast< Args&& >(args)...))) -> decltype(Function(static_cast< Args&& >(args)...))
|
||||
{
|
||||
return Function(static_cast< Args&& >(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace functor_ns
|
||||
|
||||
using functor_ns::functor;
|
||||
|
||||
} // namespace boost::core
|
||||
|
||||
#endif // BOOST_CORE_FUNCTOR_HPP
|
61
include/boost/core/identity.hpp
Normal file
61
include/boost/core/identity.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2021-2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_CORE_IDENTITY_HPP
|
||||
#define BOOST_CORE_IDENTITY_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
struct identity {
|
||||
typedef void is_transparent;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR T&& operator()(T&& value) const BOOST_NOEXCEPT {
|
||||
return std::forward<T>(value);
|
||||
}
|
||||
#else
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR const T& operator()(const T& value) const BOOST_NOEXCEPT {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR T& operator()(T& value) const BOOST_NOEXCEPT {
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class>
|
||||
struct result { };
|
||||
|
||||
template<class T>
|
||||
struct result<identity(T&)> {
|
||||
typedef T& type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<class T>
|
||||
struct result<identity(T)> {
|
||||
typedef T&& type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct result<identity(T&&)> {
|
||||
typedef T&& type;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
@ -11,34 +11,64 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template <typename... Ts>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts&& ...)
|
||||
{}
|
||||
|
||||
#else
|
||||
|
||||
template <typename... Ts>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts const& ...)
|
||||
{}
|
||||
|
||||
#endif
|
||||
|
||||
template <typename... Ts>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
|
||||
{}
|
||||
|
||||
#else
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename T1>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&)
|
||||
{}
|
||||
|
||||
template <typename T1>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&)
|
||||
{}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&)
|
||||
{}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&)
|
||||
{}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&)
|
||||
{}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&)
|
||||
{}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&, T4&)
|
||||
{}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&)
|
||||
{}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&, T4&, T5&)
|
||||
{}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&, T5 const&)
|
||||
{}
|
||||
|
93
include/boost/core/invoke_swap.hpp
Normal file
93
include/boost/core/invoke_swap.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
|
||||
// Copyright (C) 2023 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
#ifndef BOOST_CORE_INVOKE_SWAP_HPP
|
||||
#define BOOST_CORE_INVOKE_SWAP_HPP
|
||||
|
||||
// Note: the implementation of this utility contains various workarounds:
|
||||
// - invoke_swap_impl is put outside the boost namespace, to avoid infinite
|
||||
// recursion (causing stack overflow) when swapping objects of a primitive
|
||||
// type.
|
||||
// - std::swap is imported with a using-directive, rather than
|
||||
// a using-declaration, because some compilers (including MSVC 7.1,
|
||||
// Borland 5.9.3, and Intel 8.1) don't do argument-dependent lookup
|
||||
// when it has a using-declaration instead.
|
||||
// - The main entry function is called invoke_swap rather than swap
|
||||
// to avoid forming an infinite recursion when the arguments are not
|
||||
// swappable.
|
||||
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#if __cplusplus >= 201103L || defined(BOOST_DINKUMWARE_STDLIB)
|
||||
#include <utility> // for std::swap (C++11)
|
||||
#else
|
||||
#include <algorithm> // for std::swap (C++98)
|
||||
#endif
|
||||
#include <cstddef> // for std::size_t
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC < 40700)
|
||||
// gcc 4.6 ICEs on noexcept specifications below
|
||||
#define BOOST_CORE_SWAP_NOEXCEPT_IF(x)
|
||||
#else
|
||||
#define BOOST_CORE_SWAP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x)
|
||||
#endif
|
||||
|
||||
namespace boost_swap_impl {
|
||||
|
||||
// we can't use type_traits here
|
||||
|
||||
template<class T> struct is_const { enum _vt { value = 0 }; };
|
||||
template<class T> struct is_const<T const> { enum _vt { value = 1 }; };
|
||||
|
||||
// Use std::swap if argument dependent lookup fails.
|
||||
// We need to have this at namespace scope to be able to use unqualified swap() call
|
||||
// in noexcept specification.
|
||||
using namespace std;
|
||||
|
||||
template<class T>
|
||||
BOOST_GPU_ENABLED
|
||||
inline void invoke_swap_impl(T& left, T& right) BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(swap(left, right)))
|
||||
{
|
||||
swap(left, right);
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
BOOST_GPU_ENABLED
|
||||
inline void invoke_swap_impl(T (& left)[N], T (& right)[N])
|
||||
BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::invoke_swap_impl(left[0], right[0])))
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
::boost_swap_impl::invoke_swap_impl(left[i], right[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace boost_swap_impl
|
||||
|
||||
namespace boost {
|
||||
namespace core {
|
||||
|
||||
template<class T>
|
||||
BOOST_GPU_ENABLED
|
||||
inline typename enable_if_c< !::boost_swap_impl::is_const<T>::value >::type
|
||||
invoke_swap(T& left, T& right)
|
||||
BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::invoke_swap_impl(left, right)))
|
||||
{
|
||||
::boost_swap_impl::invoke_swap_impl(left, right);
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_CORE_SWAP_NOEXCEPT_IF
|
||||
|
||||
#endif // BOOST_CORE_INVOKE_SWAP_HPP
|
@ -1,12 +1,6 @@
|
||||
#ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED
|
||||
#define BOOST_CORE_IS_SAME_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// is_same<T1,T2>::value is true when T1 == T2
|
||||
//
|
||||
// Copyright 2014 Peter Dimov
|
||||
@ -16,6 +10,15 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/detail/is_same.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
|
||||
BOOST_HEADER_DEPRECATED("<boost/type_traits/is_same.hpp>")
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@ -23,15 +26,7 @@ namespace boost
|
||||
namespace core
|
||||
{
|
||||
|
||||
template< class T1, class T2 > struct is_same
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = false );
|
||||
};
|
||||
|
||||
template< class T > struct is_same< T, T >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = true );
|
||||
};
|
||||
using boost::core::detail::is_same;
|
||||
|
||||
} // namespace core
|
||||
|
||||
|
69
include/boost/core/launder.hpp
Normal file
69
include/boost/core/launder.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef BOOST_CORE_LAUNDER_HPP_INCLUDED
|
||||
#define BOOST_CORE_LAUNDER_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__builtin_launder)
|
||||
# define BOOST_CORE_HAS_BUILTIN_LAUNDER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC < 1920
|
||||
|
||||
// msvc-14.1 suffers from internal compiler errors when using std::launder
|
||||
// https://github.com/boostorg/core/issues/160
|
||||
// https://github.com/boostorg/optional/issues/122
|
||||
|
||||
#elif (BOOST_CXX_VERSION >= 201703L) && !defined(BOOST_CORE_HAS_BUILTIN_LAUNDER)
|
||||
|
||||
#include <new>
|
||||
|
||||
#if defined(__cpp_lib_launder)
|
||||
# define BOOST_CORE_HAS_STD_LAUNDER
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
#if defined(BOOST_CORE_HAS_BUILTIN_LAUNDER)
|
||||
|
||||
template<class T> T* launder( T* p )
|
||||
{
|
||||
return __builtin_launder( p );
|
||||
}
|
||||
|
||||
#elif defined(BOOST_CORE_HAS_STD_LAUNDER)
|
||||
|
||||
template<class T> T* launder( T* p )
|
||||
{
|
||||
return std::launder( p );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class T> T* launder( T* p )
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_LAUNDER_HPP_INCLUDED
|
@ -22,13 +22,17 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/core/detail/lwt_unattended.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
#include <cctype>
|
||||
|
||||
// IDE's like Visual Studio perform better if output goes to std::cout or
|
||||
// some other stream, so allow user to configure output stream:
|
||||
@ -38,36 +42,39 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class test_result {
|
||||
class test_result
|
||||
{
|
||||
public:
|
||||
test_result()
|
||||
: report_(false)
|
||||
, errors_(0) {
|
||||
#if defined(_MSC_VER) && (_MSC_VER > 1310)
|
||||
::_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
|
||||
#endif
|
||||
|
||||
test_result(): report_( false ), errors_( 0 )
|
||||
{
|
||||
core::detail::lwt_unattended();
|
||||
}
|
||||
|
||||
~test_result() {
|
||||
if (!report_) {
|
||||
~test_result()
|
||||
{
|
||||
if( !report_ )
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "main() should return report_errors()" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
int& errors() {
|
||||
int& errors()
|
||||
{
|
||||
return errors_;
|
||||
}
|
||||
|
||||
void done() {
|
||||
void done()
|
||||
{
|
||||
report_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool report_;
|
||||
int errors_;
|
||||
};
|
||||
@ -83,12 +90,21 @@ inline int& test_errors()
|
||||
return test_results().errors();
|
||||
}
|
||||
|
||||
inline void test_failed_impl(char const * expr, char const * file, int line, char const * function)
|
||||
inline bool test_impl(char const * expr, char const * file, int line, char const * function, bool v)
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): test '" << expr << "' failed in function '"
|
||||
<< function << "'" << std::endl;
|
||||
++test_results().errors();
|
||||
if( v )
|
||||
{
|
||||
test_results();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): test '" << expr << "' failed in function '"
|
||||
<< function << "'" << std::endl;
|
||||
++test_results().errors();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void error_impl(char const * msg, char const * file, int line, char const * function)
|
||||
@ -99,14 +115,30 @@ inline void error_impl(char const * msg, char const * file, int line, char const
|
||||
++test_results().errors();
|
||||
}
|
||||
|
||||
inline void throw_failed_impl(char const * excep, char const * file, int line, char const * function)
|
||||
inline void throw_failed_impl(const char* expr, char const * excep, char const * file, int line, char const * function)
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): Exception '" << excep << "' not thrown in function '"
|
||||
<< file << "(" << line << "): expression '" << expr << "' did not throw exception '" << excep << "' in function '"
|
||||
<< function << "'" << std::endl;
|
||||
++test_results().errors();
|
||||
}
|
||||
|
||||
inline void no_throw_failed_impl(const char* expr, const char* file, int line, const char* function)
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): expression '" << expr << "' threw an exception in function '"
|
||||
<< function << "'" << std::endl;
|
||||
++test_results().errors();
|
||||
}
|
||||
|
||||
inline void no_throw_failed_impl(const char* expr, const char* what, const char* file, int line, const char* function)
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): expression '" << expr << "' threw an exception in function '"
|
||||
<< function << "': " << what << std::endl;
|
||||
++test_results().errors();
|
||||
}
|
||||
|
||||
// In the comparisons below, it is possible that T and U are signed and unsigned integer types, which generates warnings in some compilers.
|
||||
// A cleaner fix would require common_type trait or some meta-programming, which would introduce a dependency on Boost.TypeTraits. To avoid
|
||||
// the dependency we just disable the warnings.
|
||||
@ -121,6 +153,7 @@ inline void throw_failed_impl(char const * excep, char const * file, int line, c
|
||||
#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
# pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
|
||||
// specialize test output for char pointers to avoid printing as cstring
|
||||
@ -137,67 +170,151 @@ template<class T> inline const void* test_output_impl(T volatile* v) { return co
|
||||
inline const void* test_output_impl(std::nullptr_t) { return nullptr; }
|
||||
#endif
|
||||
|
||||
struct lw_test_eq {
|
||||
// print chars as numeric
|
||||
|
||||
inline int test_output_impl( signed char const& v ) { return v; }
|
||||
inline unsigned test_output_impl( unsigned char const& v ) { return v; }
|
||||
|
||||
// Whether wchar_t is signed is implementation-defined
|
||||
|
||||
template<bool Signed> struct lwt_long_type {};
|
||||
template<> struct lwt_long_type<true> { typedef long type; };
|
||||
template<> struct lwt_long_type<false> { typedef unsigned long type; };
|
||||
|
||||
inline lwt_long_type<(static_cast<wchar_t>(-1) < static_cast<wchar_t>(0))>::type test_output_impl( wchar_t const& v ) { return v; }
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_CHAR16_T )
|
||||
inline unsigned long test_output_impl( char16_t const& v ) { return v; }
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_CHAR32_T )
|
||||
inline unsigned long test_output_impl( char32_t const& v ) { return v; }
|
||||
#endif
|
||||
|
||||
inline std::string test_output_impl( char const& v )
|
||||
{
|
||||
if( std::isprint( static_cast<unsigned char>( v ) ) )
|
||||
{
|
||||
return std::string( 1, v );
|
||||
}
|
||||
else
|
||||
{
|
||||
static const char char_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
char buffer[ 4 ];
|
||||
buffer[ 0 ] = '\\';
|
||||
buffer[ 1 ] = 'x';
|
||||
buffer[ 2 ] = char_table[ (static_cast<unsigned char>( v ) >> 4u) & 0x0f ];
|
||||
buffer[ 3 ] = char_table[ static_cast<unsigned char>( v ) & 0x0f ];
|
||||
|
||||
return std::string( buffer, 4u );
|
||||
}
|
||||
}
|
||||
|
||||
// predicates
|
||||
|
||||
struct lw_test_eq
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t == u; }
|
||||
static const char* op() { return "=="; }
|
||||
};
|
||||
|
||||
struct lw_test_ne {
|
||||
struct lw_test_ne
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t != u; }
|
||||
static const char* op() { return "!="; }
|
||||
};
|
||||
|
||||
struct lw_test_lt {
|
||||
struct lw_test_lt
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t < u; }
|
||||
static const char* op() { return "<"; }
|
||||
};
|
||||
|
||||
struct lw_test_le {
|
||||
struct lw_test_le
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t <= u; }
|
||||
static const char* op() { return "<="; }
|
||||
};
|
||||
|
||||
struct lw_test_gt {
|
||||
struct lw_test_gt
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t > u; }
|
||||
static const char* op() { return ">"; }
|
||||
};
|
||||
|
||||
struct lw_test_ge {
|
||||
struct lw_test_ge
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t >= u; }
|
||||
static const char* op() { return ">="; }
|
||||
};
|
||||
|
||||
// lwt_predicate_name
|
||||
|
||||
template<class T> char const * lwt_predicate_name( T const& )
|
||||
{
|
||||
return "~=";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_eq const& )
|
||||
{
|
||||
return "==";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_ne const& )
|
||||
{
|
||||
return "!=";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_lt const& )
|
||||
{
|
||||
return "<";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_le const& )
|
||||
{
|
||||
return "<=";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_gt const& )
|
||||
{
|
||||
return ">";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_ge const& )
|
||||
{
|
||||
return ">=";
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
template<class BinaryPredicate, class T, class U>
|
||||
inline void test_with_impl(BinaryPredicate pred, char const * expr1, char const * expr2,
|
||||
inline bool test_with_impl(BinaryPredicate pred, char const * expr1, char const * expr2,
|
||||
char const * file, int line, char const * function,
|
||||
T const & t, U const & u)
|
||||
{
|
||||
if( pred(t, u) )
|
||||
{
|
||||
test_results();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): test '" << expr1 << " " << pred.op() << " " << expr2
|
||||
<< "' ('" << test_output_impl(t) << "' " << pred.op() << " '" << test_output_impl(u)
|
||||
<< file << "(" << line << "): test '" << expr1 << " " << lwt_predicate_name(pred) << " " << expr2
|
||||
<< "' ('" << test_output_impl(t) << "' " << lwt_predicate_name(pred) << " '" << test_output_impl(u)
|
||||
<< "') failed in function '" << function << "'" << std::endl;
|
||||
++test_results().errors();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void test_cstr_eq_impl( char const * expr1, char const * expr2,
|
||||
inline bool test_cstr_eq_impl( char const * expr1, char const * expr2,
|
||||
char const * file, int line, char const * function, char const * const t, char const * const u )
|
||||
{
|
||||
if( std::strcmp(t, u) == 0 )
|
||||
{
|
||||
test_results();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -205,15 +322,17 @@ inline void test_cstr_eq_impl( char const * expr1, char const * expr2,
|
||||
<< file << "(" << line << "): test '" << expr1 << " == " << expr2 << "' ('" << t
|
||||
<< "' == '" << u << "') failed in function '" << function << "'" << std::endl;
|
||||
++test_results().errors();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void test_cstr_ne_impl( char const * expr1, char const * expr2,
|
||||
inline bool test_cstr_ne_impl( char const * expr1, char const * expr2,
|
||||
char const * file, int line, char const * function, char const * const t, char const * const u )
|
||||
{
|
||||
if( std::strcmp(t, u) != 0 )
|
||||
{
|
||||
test_results();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -221,11 +340,12 @@ inline void test_cstr_ne_impl( char const * expr1, char const * expr2,
|
||||
<< file << "(" << line << "): test '" << expr1 << " != " << expr2 << "' ('" << t
|
||||
<< "' != '" << u << "') failed in function '" << function << "'" << std::endl;
|
||||
++test_results().errors();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<class FormattedOutputFunction, class InputIterator1, class InputIterator2>
|
||||
void test_all_eq_impl(FormattedOutputFunction& output,
|
||||
bool test_all_eq_impl(FormattedOutputFunction& output,
|
||||
char const * file, int line, char const * function,
|
||||
InputIterator1 first_begin, InputIterator1 first_end,
|
||||
InputIterator2 second_begin, InputIterator2 second_end)
|
||||
@ -284,16 +404,18 @@ void test_all_eq_impl(FormattedOutputFunction& output,
|
||||
if (error_count == 0)
|
||||
{
|
||||
test_results();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
output << std::endl;
|
||||
++test_results().errors();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<class FormattedOutputFunction, class InputIterator1, class InputIterator2, typename BinaryPredicate>
|
||||
void test_all_with_impl(FormattedOutputFunction& output,
|
||||
bool test_all_with_impl(FormattedOutputFunction& output,
|
||||
char const * file, int line, char const * function,
|
||||
InputIterator1 first_begin, InputIterator1 first_end,
|
||||
InputIterator2 second_begin, InputIterator2 second_end,
|
||||
@ -353,11 +475,13 @@ void test_all_with_impl(FormattedOutputFunction& output,
|
||||
if (error_count == 0)
|
||||
{
|
||||
test_results();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
output << std::endl;
|
||||
++test_results().errors();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,13 +519,24 @@ inline int report_errors()
|
||||
return errors < 256? errors: 255;
|
||||
}
|
||||
|
||||
namespace core
|
||||
{
|
||||
|
||||
inline void lwt_init()
|
||||
{
|
||||
boost::detail::test_results();
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_TEST(expr) ((expr)? (void)::boost::detail::test_results(): ::boost::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION))
|
||||
#define BOOST_TEST(expr) ( ::boost::detail::test_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, (expr)? true: false) )
|
||||
#define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr))
|
||||
|
||||
#define BOOST_ERROR(msg) ( ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||
|
||||
#define BOOST_TEST_WITH(expr1,expr2,predicate) ( ::boost::detail::test_with_impl(predicate, #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
|
||||
|
||||
#define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_eq(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
|
||||
#define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_ne(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
|
||||
|
||||
@ -417,22 +552,38 @@ inline int report_errors()
|
||||
#define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) ( ::boost::detail::test_all_with_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2, predicate) )
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#define BOOST_TEST_THROWS( EXPR, EXCEP ) \
|
||||
try { \
|
||||
EXPR; \
|
||||
::boost::detail::throw_failed_impl \
|
||||
(#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
|
||||
} \
|
||||
catch(EXCEP const&) { \
|
||||
::boost::detail::test_results(); \
|
||||
} \
|
||||
catch(...) { \
|
||||
::boost::detail::throw_failed_impl \
|
||||
(#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
|
||||
} \
|
||||
#define BOOST_TEST_THROWS( EXPR, EXCEP ) \
|
||||
try { \
|
||||
EXPR; \
|
||||
::boost::detail::throw_failed_impl \
|
||||
(#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
|
||||
} \
|
||||
catch(EXCEP const&) { \
|
||||
::boost::detail::test_results(); \
|
||||
} \
|
||||
catch(...) { \
|
||||
::boost::detail::throw_failed_impl \
|
||||
(#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
|
||||
} \
|
||||
//
|
||||
#else
|
||||
#define BOOST_TEST_THROWS( EXPR, EXCEP )
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
# define BOOST_TEST_NO_THROW(EXPR) \
|
||||
try { \
|
||||
EXPR; \
|
||||
} catch (const std::exception& e) { \
|
||||
::boost::detail::no_throw_failed_impl \
|
||||
(#EXPR, e.what(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
|
||||
} catch (...) { \
|
||||
::boost::detail::no_throw_failed_impl \
|
||||
(#EXPR, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
|
||||
}
|
||||
//
|
||||
#else
|
||||
# define BOOST_TEST_NO_THROW(EXPR) { EXPR; }
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP
|
||||
|
@ -11,7 +11,7 @@
|
||||
//
|
||||
// BOOST_TEST_TRAIT_TRUE, BOOST_TEST_TRAIT_FALSE, BOOST_TEST_TRAIT_SAME
|
||||
//
|
||||
// Copyright 2014 Peter Dimov
|
||||
// Copyright 2014, 2021 Peter Dimov
|
||||
//
|
||||
// Copyright 2019 Glen Joseph Fernandes
|
||||
// (glenjofe@gmail.com)
|
||||
@ -21,60 +21,15 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/typeinfo.hpp>
|
||||
#include <boost/core/is_same.hpp>
|
||||
#include <boost/core/type_name.hpp>
|
||||
#include <boost/core/detail/is_same.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class, int = 0> struct test_print { };
|
||||
|
||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T, 2>)
|
||||
{
|
||||
return o << boost::core::demangled_name(BOOST_CORE_TYPEID(T));
|
||||
}
|
||||
|
||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T, 1>)
|
||||
{
|
||||
return o << test_print<T, 2>();
|
||||
}
|
||||
|
||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<const T, 1>)
|
||||
{
|
||||
return o << test_print<T, 2>() << " const";
|
||||
}
|
||||
|
||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<volatile T, 1>)
|
||||
{
|
||||
return o << test_print<T, 2>() << " volatile";
|
||||
}
|
||||
|
||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<const volatile T, 1>)
|
||||
{
|
||||
return o << test_print<T, 2>() << " const volatile";
|
||||
}
|
||||
|
||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T>)
|
||||
{
|
||||
return o << test_print<T, 1>();
|
||||
}
|
||||
|
||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T&>)
|
||||
{
|
||||
return o << test_print<T, 1>() << " &";
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T&&>)
|
||||
{
|
||||
return o << test_print<T, 1>() << " &&";
|
||||
}
|
||||
#endif
|
||||
|
||||
template< class T > inline void test_trait_impl( char const * trait, void (*)( T ),
|
||||
bool expected, char const * file, int line, char const * function )
|
||||
{
|
||||
@ -86,7 +41,7 @@ template< class T > inline void test_trait_impl( char const * trait, void (*)( T
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): predicate '" << trait << "' ["
|
||||
<< boost::core::demangled_name( BOOST_CORE_TYPEID(T) ) << "]"
|
||||
<< boost::core::type_name<T>() << "]"
|
||||
<< " test failed in function '" << function
|
||||
<< "' (should have been " << ( expected? "true": "false" ) << ")"
|
||||
<< std::endl;
|
||||
@ -101,7 +56,7 @@ template<class T> inline bool test_trait_same_impl_( T )
|
||||
}
|
||||
|
||||
template<class T1, class T2> inline void test_trait_same_impl( char const * types,
|
||||
boost::core::is_same<T1, T2> same, char const * file, int line, char const * function )
|
||||
boost::core::detail::is_same<T1, T2> same, char const * file, int line, char const * function )
|
||||
{
|
||||
if( test_trait_same_impl_( same ) )
|
||||
{
|
||||
@ -112,8 +67,8 @@ template<class T1, class T2> inline void test_trait_same_impl( char const * type
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): test 'is_same<" << types << ">'"
|
||||
<< " failed in function '" << function
|
||||
<< "' ('" << test_print<T1>()
|
||||
<< "' != '" << test_print<T2>() << "')"
|
||||
<< "' ('" << boost::core::type_name<T1>()
|
||||
<< "' != '" << boost::core::type_name<T2>() << "')"
|
||||
<< std::endl;
|
||||
|
||||
++test_results().errors();
|
||||
@ -121,11 +76,16 @@ template<class T1, class T2> inline void test_trait_same_impl( char const * type
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_TEST_TRAIT_TRUE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, true, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||
#define BOOST_TEST_TRAIT_FALSE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, false, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||
#define BOOST_TEST_TRAIT_SAME(...) ( ::boost::detail::test_trait_same_impl(#__VA_ARGS__, ::boost::core::is_same<__VA_ARGS__>(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// ignoring -Wvariadic-macros with #pragma doesn't work under GCC
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#define BOOST_TEST_TRAIT_SAME(...) ( ::boost::detail::test_trait_same_impl(#__VA_ARGS__, ::boost::core::detail::is_same< __VA_ARGS__ >(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||
|
||||
#endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_TRAIT_HPP
|
||||
|
59
include/boost/core/make_span.hpp
Normal file
59
include/boost/core/make_span.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_CORE_MAKE_SPAN_HPP
|
||||
#define BOOST_CORE_MAKE_SPAN_HPP
|
||||
|
||||
#include <boost/core/span.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class I>
|
||||
inline constexpr span<I>
|
||||
make_span(I* f, std::size_t c) noexcept
|
||||
{
|
||||
return span<I>(f, c);
|
||||
}
|
||||
|
||||
template<class I>
|
||||
inline constexpr span<I>
|
||||
make_span(I* f, I* l) noexcept
|
||||
{
|
||||
return span<I>(f, l);
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline constexpr span<T, N>
|
||||
make_span(T(&a)[N]) noexcept
|
||||
{
|
||||
return span<T, N>(a);
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline constexpr span<T, N>
|
||||
make_span(std::array<T, N>& a) noexcept
|
||||
{
|
||||
return span<T, N>(a);
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline constexpr span<const T, N>
|
||||
make_span(const std::array<T, N>& a) noexcept
|
||||
{
|
||||
return span<const T, N>(a);
|
||||
}
|
||||
|
||||
template<class R>
|
||||
inline span<typename detail::span_data<R>::type>
|
||||
make_span(R&& r)
|
||||
{
|
||||
return span<typename detail::span_data<R>::type>(std::forward<R>(r));
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
82
include/boost/core/max_align.hpp
Normal file
82
include/boost/core/max_align.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef BOOST_CORE_MAX_ALIGN_HPP_INCLUDED
|
||||
#define BOOST_CORE_MAX_ALIGN_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/alignof.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
// BOOST_CORE_HAS_FLOAT128
|
||||
|
||||
#if defined(BOOST_HAS_FLOAT128)
|
||||
|
||||
# define BOOST_CORE_HAS_FLOAT128
|
||||
|
||||
#elif defined(__SIZEOF_FLOAT128__)
|
||||
|
||||
# define BOOST_CORE_HAS_FLOAT128
|
||||
|
||||
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) && defined(__i386__)
|
||||
|
||||
# define BOOST_CORE_HAS_FLOAT128
|
||||
|
||||
#endif
|
||||
|
||||
// max_align_t, max_align
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
union max_align_t
|
||||
{
|
||||
char c;
|
||||
short s;
|
||||
int i;
|
||||
long l;
|
||||
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
|
||||
boost::long_long_type ll;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
|
||||
boost::int128_type i128;
|
||||
|
||||
#endif
|
||||
|
||||
float f;
|
||||
double d;
|
||||
long double ld;
|
||||
|
||||
#if defined(BOOST_CORE_HAS_FLOAT128)
|
||||
|
||||
__float128 f128;
|
||||
|
||||
#endif
|
||||
|
||||
void* p;
|
||||
void (*pf) ();
|
||||
|
||||
int max_align_t::* pm;
|
||||
void (max_align_t::*pmf)();
|
||||
};
|
||||
|
||||
BOOST_CONSTEXPR_OR_CONST std::size_t max_align = BOOST_CORE_ALIGNOF( max_align_t );
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_MAX_ALIGN_HPP_INCLUDED
|
108
include/boost/core/memory_resource.hpp
Normal file
108
include/boost/core/memory_resource.hpp
Normal file
@ -0,0 +1,108 @@
|
||||
#ifndef BOOST_CORE_MEMORY_RESOURCE_HPP_INCLUDED
|
||||
#define BOOST_CORE_MEMORY_RESOURCE_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/max_align.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
// Define our own placement new to avoid the inclusion of <new>
|
||||
// (~9K extra lines) at Ion Gaztanhaga's request.
|
||||
//
|
||||
// We can use our own because [intro.object] p13 says:
|
||||
//
|
||||
// Any implicit or explicit invocation of a function named `operator new`
|
||||
// or `operator new[]` implicitly creates objects in the returned region of
|
||||
// storage and returns a pointer to a suitable created object.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct placement_new_tag {};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
inline void* operator new( std::size_t, void* p, boost::core::detail::placement_new_tag )
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
inline void operator delete( void*, void*, boost::core::detail::placement_new_tag )
|
||||
{
|
||||
}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
class memory_resource
|
||||
{
|
||||
public:
|
||||
|
||||
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || BOOST_WORKAROUND(BOOST_GCC, < 40700)
|
||||
|
||||
virtual ~memory_resource() {}
|
||||
|
||||
#else
|
||||
|
||||
virtual ~memory_resource() = default;
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_ATTRIBUTE_NODISCARD void* allocate( std::size_t bytes, std::size_t alignment = max_align )
|
||||
{
|
||||
// https://github.com/boostorg/container/issues/199
|
||||
// https://cplusplus.github.io/LWG/issue3471
|
||||
|
||||
return ::operator new( bytes, do_allocate( bytes, alignment ), core::detail::placement_new_tag() );
|
||||
}
|
||||
|
||||
void deallocate( void* p, std::size_t bytes, std::size_t alignment = max_align )
|
||||
{
|
||||
do_deallocate( p, bytes, alignment );
|
||||
}
|
||||
|
||||
bool is_equal( memory_resource const & other ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return do_is_equal( other );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
virtual void* do_allocate( std::size_t bytes, std::size_t alignment ) = 0;
|
||||
virtual void do_deallocate( void* p, std::size_t bytes, std::size_t alignment ) = 0;
|
||||
|
||||
virtual bool do_is_equal( memory_resource const & other ) const BOOST_NOEXCEPT = 0;
|
||||
};
|
||||
|
||||
inline bool operator==( memory_resource const& a, memory_resource const& b ) BOOST_NOEXCEPT
|
||||
{
|
||||
return &a == &b || a.is_equal( b );
|
||||
}
|
||||
|
||||
inline bool operator!=( memory_resource const& a, memory_resource const& b ) BOOST_NOEXCEPT
|
||||
{
|
||||
return !( a == b );
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_MEMORY_RESOURCE_HPP_INCLUDED
|
@ -29,7 +29,7 @@
|
||||
# define BOOST_RETHROW throw;
|
||||
# define BOOST_CATCH_END }
|
||||
#else
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
|
||||
# define BOOST_TRY { if ("")
|
||||
# define BOOST_CATCH(x) else if (!"")
|
||||
# elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
|
||||
|
@ -8,28 +8,18 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef BOOST_CORE_NOINIT_ADAPTOR_HPP
|
||||
#define BOOST_CORE_NOINIT_ADAPTOR_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <memory>
|
||||
#endif
|
||||
#include <new>
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#include <utility>
|
||||
#endif
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class A>
|
||||
struct noinit_adaptor
|
||||
: A {
|
||||
typedef void _default_construct_destroy;
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef noinit_adaptor<typename std::allocator_traits<A>::template
|
||||
rebind_alloc<U> > other;
|
||||
#else
|
||||
typedef noinit_adaptor<typename A::template rebind<U>::other> other;
|
||||
#endif
|
||||
typedef noinit_adaptor<typename allocator_rebind<A, U>::type> other;
|
||||
};
|
||||
|
||||
noinit_adaptor()
|
||||
@ -43,44 +33,32 @@ struct noinit_adaptor
|
||||
template<class U>
|
||||
noinit_adaptor(const U& u) BOOST_NOEXCEPT
|
||||
: A(u) { }
|
||||
|
||||
template<class U>
|
||||
noinit_adaptor(U& u) BOOST_NOEXCEPT
|
||||
: A(u) { }
|
||||
#endif
|
||||
|
||||
template<class U>
|
||||
noinit_adaptor(const noinit_adaptor<U>& u) BOOST_NOEXCEPT
|
||||
: A(static_cast<const U&>(u)) { }
|
||||
: A(static_cast<const A&>(u)) { }
|
||||
|
||||
template<class U>
|
||||
void construct(U* p) {
|
||||
::new((void*)p) U;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class U, class V, class... Args>
|
||||
void construct(U* p, V&& v, Args&&... args) {
|
||||
::new((void*)p) U(std::forward<V>(v), std::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
template<class U, class V>
|
||||
void construct(U* p, V&& v) {
|
||||
::new((void*)p) U(std::forward<V>(v));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class U, class V>
|
||||
void construct(U* p, const V& v) {
|
||||
::new((void*)p) U(v);
|
||||
}
|
||||
|
||||
template<class U, class V>
|
||||
void construct(U* p, V& v) {
|
||||
::new((void*)p) U(v);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class U>
|
||||
void destroy(U* p) {
|
||||
p->~U();
|
||||
(void)p;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace noncopyable_ // protection from unintended ADL
|
||||
// whether a type derives from noncopyable without needing the definition
|
||||
// of noncopyable itself.
|
||||
//
|
||||
// The definition of base_token is macro-guarded so that Type Trais can
|
||||
// The definition of base_token is macro-guarded so that Type Traits can
|
||||
// define it locally without including this header, to avoid a dependency
|
||||
// on Core.
|
||||
|
||||
|
@ -27,6 +27,9 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Block unintended ADL
|
||||
namespace null_deleter_ns {
|
||||
|
||||
//! A function object that does nothing and can be used as an empty deleter for \c shared_ptr
|
||||
struct null_deleter
|
||||
{
|
||||
@ -39,6 +42,10 @@ struct null_deleter
|
||||
void operator() (T*) const BOOST_NOEXCEPT {}
|
||||
};
|
||||
|
||||
} // namespace null_deleter_ns
|
||||
|
||||
using null_deleter_ns::null_deleter;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_CORE_NULL_DELETER_HPP
|
||||
|
49
include/boost/core/pointer_in_range.hpp
Normal file
49
include/boost/core/pointer_in_range.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2024 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_CORE_POINTER_IN_RANGE_HPP
|
||||
#define BOOST_CORE_POINTER_IN_RANGE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <functional>
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC >= 1925
|
||||
#define BOOST_CORE_DETAIL_HAS_IS_CONSTEVAL
|
||||
#elif defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_is_constant_evaluated)
|
||||
#define BOOST_CORE_DETAIL_HAS_IS_CONSTEVAL
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_CORE_DETAIL_HAS_IS_CONSTEVAL)
|
||||
#define BOOST_CORE_NO_CONSTEXPR_POINTER_IN_RANGE
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CONSTEXPR bool
|
||||
pointer_in_range(const T* p, const T* b, const T* e)
|
||||
{
|
||||
#if defined(BOOST_CORE_DETAIL_HAS_IS_CONSTEVAL)
|
||||
if ( __builtin_is_constant_evaluated()) {
|
||||
for (; b != e; ++b) {
|
||||
if (b == p) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return std::less_equal<const T*>()(b, p) && std::less<const T*>()(p, e);
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017-2018 Glen Joseph Fernandes
|
||||
Copyright 2017-2021 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
@ -9,42 +9,23 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#define BOOST_CORE_POINTER_TRAITS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
|
||||
#include <memory>
|
||||
#else
|
||||
#include <boost/core/addressof.hpp>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
|
||||
template<class T>
|
||||
struct pointer_traits
|
||||
: std::pointer_traits<T> {
|
||||
template<class U>
|
||||
struct rebind_to {
|
||||
typedef typename std::pointer_traits<T>::template rebind<U> type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct pointer_traits<T*>
|
||||
: std::pointer_traits<T*> {
|
||||
template<class U>
|
||||
struct rebind_to {
|
||||
typedef U* type;
|
||||
};
|
||||
};
|
||||
#else
|
||||
namespace detail {
|
||||
|
||||
struct ptr_none { };
|
||||
|
||||
template<class>
|
||||
struct ptr_void {
|
||||
struct ptr_valid {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ptr_first;
|
||||
template<class>
|
||||
struct ptr_first {
|
||||
typedef ptr_none type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<template<class, class...> class T, class U, class... Args>
|
||||
@ -74,7 +55,7 @@ struct ptr_element {
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ptr_element<T, typename ptr_void<typename T::element_type>::type> {
|
||||
struct ptr_element<T, typename ptr_valid<typename T::element_type>::type> {
|
||||
typedef typename T::element_type type;
|
||||
};
|
||||
|
||||
@ -85,12 +66,12 @@ struct ptr_difference {
|
||||
|
||||
template<class T>
|
||||
struct ptr_difference<T,
|
||||
typename ptr_void<typename T::difference_type>::type> {
|
||||
typename ptr_valid<typename T::difference_type>::type> {
|
||||
typedef typename T::difference_type type;
|
||||
};
|
||||
|
||||
template<class T, class V>
|
||||
struct ptr_transform;
|
||||
template<class, class>
|
||||
struct ptr_transform { };
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<template<class, class...> class T, class U, class... Args, class V>
|
||||
@ -116,68 +97,139 @@ struct ptr_transform<T<U1, U2, U3>, V> {
|
||||
#endif
|
||||
|
||||
template<class T, class U, class = void>
|
||||
struct ptr_rebind {
|
||||
typedef typename ptr_transform<T, U>::type type;
|
||||
};
|
||||
struct ptr_rebind
|
||||
: ptr_transform<T, U> { };
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
template<class T, class U>
|
||||
struct ptr_rebind<T, U,
|
||||
typename ptr_void<typename T::template rebind<U> >::type> {
|
||||
typename ptr_valid<typename T::template rebind<U> >::type> {
|
||||
typedef typename T::template rebind<U> type;
|
||||
};
|
||||
#else
|
||||
template<class T, class U>
|
||||
struct ptr_rebind<T, U,
|
||||
typename ptr_valid<typename T::template rebind<U>::other>::type> {
|
||||
typedef typename T::template rebind<U>::other type;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
template<class T, class E>
|
||||
class ptr_to_expr {
|
||||
template<class>
|
||||
struct result {
|
||||
char x, y;
|
||||
};
|
||||
|
||||
static E& source();
|
||||
|
||||
template<class O>
|
||||
static auto check(int) -> result<decltype(O::pointer_to(source()))>;
|
||||
|
||||
template<class>
|
||||
static char check(long);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<T>(0)) > 1;
|
||||
};
|
||||
|
||||
template<class T, class E>
|
||||
struct ptr_to_expr<T*, E> {
|
||||
BOOST_STATIC_CONSTEXPR bool value = true;
|
||||
};
|
||||
|
||||
template<class T, class E>
|
||||
struct ptr_has_to {
|
||||
BOOST_STATIC_CONSTEXPR bool value = ptr_to_expr<T, E>::value;
|
||||
};
|
||||
#else
|
||||
template<class, class>
|
||||
struct ptr_has_to {
|
||||
BOOST_STATIC_CONSTEXPR bool value = true;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
struct ptr_value {
|
||||
typedef T type;
|
||||
struct ptr_has_to<T, void> {
|
||||
BOOST_STATIC_CONSTEXPR bool value = false;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ptr_value<void> {
|
||||
typedef struct { } type;
|
||||
template<class T>
|
||||
struct ptr_has_to<T, const void> {
|
||||
BOOST_STATIC_CONSTEXPR bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ptr_has_to<T, volatile void> {
|
||||
BOOST_STATIC_CONSTEXPR bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ptr_has_to<T, const volatile void> {
|
||||
BOOST_STATIC_CONSTEXPR bool value = false;
|
||||
};
|
||||
|
||||
template<class T, class E, bool = ptr_has_to<T, E>::value>
|
||||
struct ptr_to { };
|
||||
|
||||
template<class T, class E>
|
||||
struct ptr_to<T, E, true> {
|
||||
static T pointer_to(E& v) {
|
||||
return T::pointer_to(v);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ptr_to<T*, T, true> {
|
||||
static T* pointer_to(T& v) BOOST_NOEXCEPT {
|
||||
return boost::addressof(v);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class E>
|
||||
struct ptr_traits
|
||||
: ptr_to<T, E> {
|
||||
typedef T pointer;
|
||||
typedef E element_type;
|
||||
typedef typename ptr_difference<T>::type difference_type;
|
||||
|
||||
template<class U>
|
||||
struct rebind_to
|
||||
: ptr_rebind<T, U> { };
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
template<class U>
|
||||
using rebind = typename rebind_to<U>::type;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ptr_traits<T, ptr_none> { };
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class T>
|
||||
struct pointer_traits {
|
||||
typedef T pointer;
|
||||
typedef typename detail::ptr_element<T>::type element_type;
|
||||
typedef typename detail::ptr_difference<T>::type difference_type;
|
||||
template<class U>
|
||||
struct rebind_to {
|
||||
typedef typename detail::ptr_rebind<T, U>::type type;
|
||||
};
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
template<class U>
|
||||
using rebind = typename detail::ptr_rebind<T, U>::type;
|
||||
#endif
|
||||
static pointer
|
||||
pointer_to(typename detail::ptr_value<element_type>::type& v) {
|
||||
return pointer::pointer_to(v);
|
||||
}
|
||||
};
|
||||
struct pointer_traits
|
||||
: detail::ptr_traits<T, typename detail::ptr_element<T>::type> { };
|
||||
|
||||
template<class T>
|
||||
struct pointer_traits<T*> {
|
||||
struct pointer_traits<T*>
|
||||
: detail::ptr_to<T*, T> {
|
||||
typedef T* pointer;
|
||||
typedef T element_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template<class U>
|
||||
struct rebind_to {
|
||||
typedef U* type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
template<class U>
|
||||
using rebind = U*;
|
||||
using rebind = typename rebind_to<U>::type;
|
||||
#endif
|
||||
static T*
|
||||
pointer_to(typename detail::ptr_value<T>::type& v) BOOST_NOEXCEPT {
|
||||
return boost::addressof(v);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR inline T*
|
||||
|
@ -16,7 +16,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstdlib>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||
|
||||
@ -33,7 +33,7 @@ extern "C" _Noreturn void quick_exit(int);
|
||||
namespace boost
|
||||
{
|
||||
|
||||
BOOST_NORETURN void quick_exit( int code ) BOOST_NOEXCEPT
|
||||
BOOST_NORETURN inline void quick_exit( int code ) BOOST_NOEXCEPT
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
#ifndef BOOST_CORE_REF_HPP
|
||||
#define BOOST_CORE_REF_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// ref.hpp - ref/cref, useful helper functions
|
||||
@ -46,6 +45,28 @@ namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< class Y, class T > struct ref_convertible
|
||||
{
|
||||
typedef char (&yes) [1];
|
||||
typedef char (&no) [2];
|
||||
|
||||
static yes f( T* );
|
||||
static no f( ... );
|
||||
|
||||
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
struct ref_empty
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// reference_wrapper
|
||||
|
||||
/**
|
||||
@ -71,11 +92,11 @@ public:
|
||||
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
|
||||
BOOST_FORCEINLINE explicit reference_wrapper(T& t) BOOST_NOEXCEPT : t_(boost::addressof(t)) {}
|
||||
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
|
||||
|
||||
BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {}
|
||||
BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ) BOOST_NOEXCEPT : t_( boost::addressof( t ) ) {}
|
||||
|
||||
#endif
|
||||
|
||||
@ -87,24 +108,46 @@ public:
|
||||
public:
|
||||
#endif
|
||||
|
||||
template<class Y> friend class reference_wrapper;
|
||||
|
||||
/**
|
||||
@return The stored reference.
|
||||
Constructs a `reference_wrapper` object that stores the
|
||||
reference stored in the compatible `reference_wrapper` `r`.
|
||||
|
||||
@remark Only enabled when `Y*` is convertible to `T*`.
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE operator T& () const { return *t_; }
|
||||
#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
template<class Y, class = typename enable_if_c<boost::detail::ref_convertible<Y, T>::value>::type>
|
||||
reference_wrapper( reference_wrapper<Y> r ) BOOST_NOEXCEPT : t_( r.t_ )
|
||||
{
|
||||
}
|
||||
#else
|
||||
template<class Y> reference_wrapper( reference_wrapper<Y> r,
|
||||
typename enable_if_c<boost::detail::ref_convertible<Y, T>::value,
|
||||
boost::detail::ref_empty>::type = boost::detail::ref_empty() ) BOOST_NOEXCEPT : t_( r.t_ )
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@return The stored reference.
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE T& get() const { return *t_; }
|
||||
BOOST_FORCEINLINE operator T& () const BOOST_NOEXCEPT { return *t_; }
|
||||
|
||||
/**
|
||||
@return The stored reference.
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE T& get() const BOOST_NOEXCEPT { return *t_; }
|
||||
|
||||
/**
|
||||
@return A pointer to the object referenced by the stored
|
||||
reference.
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE T* get_pointer() const { return t_; }
|
||||
BOOST_FORCEINLINE T* get_pointer() const BOOST_NOEXCEPT { return t_; }
|
||||
|
||||
private:
|
||||
|
||||
@ -116,7 +159,7 @@ private:
|
||||
/**
|
||||
@cond
|
||||
*/
|
||||
#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
|
||||
#if defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) )
|
||||
# define BOOST_REF_CONST
|
||||
#else
|
||||
# define BOOST_REF_CONST const
|
||||
@ -129,7 +172,7 @@ private:
|
||||
@return `reference_wrapper<T>(t)`
|
||||
@remark Does not throw.
|
||||
*/
|
||||
template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t )
|
||||
template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
|
||||
|
||||
@ -148,7 +191,7 @@ template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T
|
||||
@return `reference_wrapper<T const>(t)`
|
||||
@remark Does not throw.
|
||||
*/
|
||||
template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t )
|
||||
template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return reference_wrapper<T const>(t);
|
||||
}
|
||||
@ -279,7 +322,7 @@ template<typename T> struct unwrap_reference< reference_wrapper<T> const volatil
|
||||
@return `unwrap_reference<T>::type&(t)`
|
||||
@remark Does not throw.
|
||||
*/
|
||||
template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t )
|
||||
template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return t;
|
||||
}
|
||||
@ -289,7 +332,7 @@ template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_r
|
||||
/**
|
||||
@cond
|
||||
*/
|
||||
template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r )
|
||||
template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
return r.get_pointer();
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ namespace boost
|
||||
/**
|
||||
* Casts a scoped enum to its underlying type.
|
||||
*
|
||||
* This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type.
|
||||
* This function is useful when working with scoped enum classes, which doesn't implicitly convert to the underlying type.
|
||||
* @param v A scoped enum.
|
||||
* @returns The underlying type.
|
||||
* @throws No-throws.
|
||||
|
131
include/boost/core/serialization.hpp
Normal file
131
include/boost/core/serialization.hpp
Normal file
@ -0,0 +1,131 @@
|
||||
#ifndef BOOST_CORE_SERIALIZATION_HPP_INCLUDED
|
||||
#define BOOST_CORE_SERIALIZATION_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// Utilities needed to implement serialization support
|
||||
// without including a Boost.Serialization header
|
||||
|
||||
#include <boost/core/nvp.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace serialization
|
||||
{
|
||||
|
||||
// Forward declarations (needed for specializations)
|
||||
|
||||
template<class T> struct version;
|
||||
|
||||
class access;
|
||||
|
||||
// Our own version_type replacement. This has to be in
|
||||
// the `serialization` namespace, because its only purpose
|
||||
// is to add `serialization` as an associated namespace.
|
||||
|
||||
struct core_version_type
|
||||
{
|
||||
unsigned int version_;
|
||||
|
||||
core_version_type( unsigned int version ): version_( version ) {}
|
||||
operator unsigned int () const { return version_; }
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
|
||||
namespace core
|
||||
{
|
||||
|
||||
// nvp
|
||||
|
||||
using serialization::nvp;
|
||||
using serialization::make_nvp;
|
||||
|
||||
// split_free
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<bool IsSaving> struct load_or_save_f;
|
||||
|
||||
template<> struct load_or_save_f<true>
|
||||
{
|
||||
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
|
||||
{
|
||||
save( a, t, serialization::core_version_type( v ) );
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct load_or_save_f<false>
|
||||
{
|
||||
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
|
||||
{
|
||||
load( a, t, serialization::core_version_type( v ) );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class A, class T> inline void split_free( A& a, T& t, unsigned int v )
|
||||
{
|
||||
detail::load_or_save_f< A::is_saving::value >()( a, t, v );
|
||||
}
|
||||
|
||||
// split_member
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<bool IsSaving, class Access = serialization::access> struct load_or_save_m;
|
||||
|
||||
template<class Access> struct load_or_save_m<true, Access>
|
||||
{
|
||||
template<class A, class T> void operator()( A& a, T const& t, unsigned int v ) const
|
||||
{
|
||||
Access::member_save( a, t, v );
|
||||
}
|
||||
};
|
||||
|
||||
template<class Access> struct load_or_save_m<false, Access>
|
||||
{
|
||||
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
|
||||
{
|
||||
Access::member_load( a, t, v );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class A, class T> inline void split_member( A& a, T& t, unsigned int v )
|
||||
{
|
||||
detail::load_or_save_m< A::is_saving::value >()( a, t, v );
|
||||
}
|
||||
|
||||
// load_construct_data_adl
|
||||
|
||||
template<class Ar, class T> void load_construct_data_adl( Ar& ar, T* t, unsigned int v )
|
||||
{
|
||||
load_construct_data( ar, t, serialization::core_version_type( v ) );
|
||||
}
|
||||
|
||||
// save_construct_data_adl
|
||||
|
||||
template<class Ar, class T> void save_construct_data_adl( Ar& ar, T const* t, unsigned int v )
|
||||
{
|
||||
save_construct_data( ar, t, serialization::core_version_type( v ) );
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_SERIALIZATION_HPP_INCLUDED
|
31
include/boost/core/size.hpp
Normal file
31
include/boost/core/size.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright 2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_CORE_SIZE_HPP
|
||||
#define BOOST_CORE_SIZE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class C>
|
||||
inline constexpr auto
|
||||
size(const C& c) noexcept(noexcept(c.size())) -> decltype(c.size())
|
||||
{
|
||||
return c.size();
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline constexpr std::size_t
|
||||
size(T(&)[N]) noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
173
include/boost/core/snprintf.hpp
Normal file
173
include/boost/core/snprintf.hpp
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2022.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file snprintf.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.12.2022
|
||||
*
|
||||
* \brief The header provides more portable definition of snprintf and vsnprintf,
|
||||
* as well as \c wchar_t counterparts.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_CORE_SNPRINTF_HPP_INCLUDED_
|
||||
#define BOOST_CORE_SNPRINTF_HPP_INCLUDED_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdarg>
|
||||
#if !defined(__MINGW64_VERSION_MAJOR)
|
||||
#include <climits>
|
||||
#endif
|
||||
|
||||
// MinGW32 and MinGW-w64 provide their own snprintf implementations that are compliant with the C standard.
|
||||
#define BOOST_CORE_DETAIL_MINGW_SNPRINTF
|
||||
|
||||
#elif (defined(BOOST_MSSTL_VERSION) && BOOST_MSSTL_VERSION < 140)
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdarg>
|
||||
#include <climits>
|
||||
|
||||
// MSVC snprintfs are not conforming but they are good enough for typical use cases.
|
||||
#define BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace core {
|
||||
|
||||
#if defined(BOOST_CORE_DETAIL_MINGW_SNPRINTF) || defined(BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF)
|
||||
|
||||
#if defined(BOOST_CORE_DETAIL_MINGW_SNPRINTF)
|
||||
|
||||
inline int vsnprintf(char* buf, std::size_t size, const char* format, std::va_list args)
|
||||
{
|
||||
return __mingw_vsnprintf(buf, size, format, args);
|
||||
}
|
||||
|
||||
inline int vswprintf(wchar_t* buf, std::size_t size, const wchar_t* format, std::va_list args)
|
||||
{
|
||||
#if defined(__MINGW64_VERSION_MAJOR)
|
||||
int res = __mingw_vsnwprintf(buf, size, format, args);
|
||||
// __mingw_vsnwprintf returns the number of characters to be printed, but (v)swprintf is expected to return -1 on truncation
|
||||
if (static_cast< unsigned int >(res) >= size)
|
||||
res = -1;
|
||||
return res;
|
||||
#else
|
||||
// Legacy MinGW32 does not provide __mingw_vsnwprintf, so use _vsnwprintf from MSVC CRT
|
||||
if (BOOST_UNLIKELY(size == 0u || size > static_cast< std::size_t >(INT_MAX)))
|
||||
return -1;
|
||||
|
||||
int res = _vsnwprintf(buf, size, format, args);
|
||||
// (v)swprintf is expected to return -1 on truncation, so we only need to ensure the output is null-terminated
|
||||
if (static_cast< unsigned int >(res) >= size)
|
||||
{
|
||||
buf[size - 1u] = L'\0';
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined(BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
// '_vsnprintf': This function or variable may be unsafe. Consider using _vsnprintf_s instead.
|
||||
#pragma warning(disable: 4996)
|
||||
#endif
|
||||
|
||||
inline int vsnprintf(char* buf, std::size_t size, const char* format, std::va_list args)
|
||||
{
|
||||
if (BOOST_UNLIKELY(size == 0u))
|
||||
return 0;
|
||||
if (BOOST_UNLIKELY(size > static_cast< std::size_t >(INT_MAX)))
|
||||
return -1;
|
||||
|
||||
buf[size - 1u] = '\0';
|
||||
int res = _vsnprintf(buf, size, format, args);
|
||||
if (static_cast< unsigned int >(res) >= size)
|
||||
{
|
||||
// _vsnprintf returns -1 if the output was truncated and in case of other errors.
|
||||
// Detect truncation by checking whether the output buffer was written over entirely.
|
||||
if (buf[size - 1u] != '\0')
|
||||
{
|
||||
buf[size - 1u] = '\0';
|
||||
res = static_cast< int >(size);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int vswprintf(wchar_t* buf, std::size_t size, const wchar_t* format, std::va_list args)
|
||||
{
|
||||
if (BOOST_UNLIKELY(size == 0u || size > static_cast< std::size_t >(INT_MAX)))
|
||||
return -1;
|
||||
|
||||
int res = _vsnwprintf(buf, size, format, args);
|
||||
// (v)swprintf is expected to return -1 on truncation, so we only need to ensure the output is null-terminated
|
||||
if (static_cast< unsigned int >(res) >= size)
|
||||
{
|
||||
buf[size - 1u] = L'\0';
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
inline int snprintf(char* buf, std::size_t size, const char* format, ...)
|
||||
{
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
int res = vsnprintf(buf, size, format, args);
|
||||
va_end(args);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int swprintf(wchar_t* buf, std::size_t size, const wchar_t* format, ...)
|
||||
{
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
int res = vswprintf(buf, size, format, args);
|
||||
va_end(args);
|
||||
return res;
|
||||
}
|
||||
|
||||
#else // defined(BOOST_CORE_DETAIL_MINGW_SNPRINTF) || defined(BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF)
|
||||
|
||||
// Standard-conforming compilers already have the correct snprintfs
|
||||
using ::snprintf;
|
||||
using ::vsnprintf;
|
||||
|
||||
using ::swprintf;
|
||||
using ::vswprintf;
|
||||
|
||||
#endif // defined(BOOST_CORE_DETAIL_MINGW_SNPRINTF) || defined(BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF)
|
||||
|
||||
} // namespace core
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_CORE_SNPRINTF_HPP_INCLUDED_
|
406
include/boost/core/span.hpp
Normal file
406
include/boost/core/span.hpp
Normal file
@ -0,0 +1,406 @@
|
||||
/*
|
||||
Copyright 2019-2023 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_CORE_SPAN_HPP
|
||||
#define BOOST_CORE_SPAN_HPP
|
||||
|
||||
#include <boost/core/detail/assert.hpp>
|
||||
#include <boost/core/data.hpp>
|
||||
#include <array>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
|
||||
constexpr std::size_t dynamic_extent = static_cast<std::size_t>(-1);
|
||||
|
||||
template<class T, std::size_t E = dynamic_extent>
|
||||
class span;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class U, class T>
|
||||
struct span_convertible {
|
||||
static constexpr bool value = std::is_convertible<U(*)[], T(*)[]>::value;
|
||||
};
|
||||
|
||||
template<std::size_t E, std::size_t N>
|
||||
struct span_capacity {
|
||||
static constexpr bool value = E == boost::dynamic_extent || E == N;
|
||||
};
|
||||
|
||||
template<class T, std::size_t E, class U, std::size_t N>
|
||||
struct span_compatible {
|
||||
static constexpr bool value = span_capacity<E, N>::value &&
|
||||
span_convertible<U, T>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using span_uncvref = typename std::remove_cv<typename
|
||||
std::remove_reference<T>::type>::type;
|
||||
|
||||
template<class>
|
||||
struct span_is_span {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template<class T, std::size_t E>
|
||||
struct span_is_span<boost::span<T, E> > {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct span_is_array {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct span_is_array<std::array<T, N> > {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using span_ptr = decltype(boost::data(std::declval<T&>()));
|
||||
|
||||
template<class, class = void>
|
||||
struct span_data { };
|
||||
|
||||
template<class T>
|
||||
struct span_data<T,
|
||||
typename std::enable_if<std::is_pointer<span_ptr<T> >::value>::type> {
|
||||
typedef typename std::remove_pointer<span_ptr<T> >::type type;
|
||||
};
|
||||
|
||||
template<class, class, class = void>
|
||||
struct span_has_data {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template<class R, class T>
|
||||
struct span_has_data<R, T, typename std::enable_if<span_convertible<typename
|
||||
span_data<R>::type, T>::value>::type> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template<class, class = void>
|
||||
struct span_has_size {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template<class R>
|
||||
struct span_has_size<R, typename
|
||||
std::enable_if<std::is_convertible<decltype(std::declval<R&>().size()),
|
||||
std::size_t>::value>::type> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template<class R, class T>
|
||||
struct span_is_range {
|
||||
static constexpr bool value = (std::is_const<T>::value ||
|
||||
std::is_lvalue_reference<R>::value) &&
|
||||
!span_is_span<span_uncvref<R> >::value &&
|
||||
!span_is_array<span_uncvref<R> >::value &&
|
||||
!std::is_array<span_uncvref<R> >::value &&
|
||||
span_has_data<R, T>::value &&
|
||||
span_has_size<R>::value;
|
||||
};
|
||||
|
||||
template<std::size_t E, std::size_t N>
|
||||
struct span_implicit {
|
||||
static constexpr bool value = E == boost::dynamic_extent ||
|
||||
N != boost::dynamic_extent;
|
||||
};
|
||||
|
||||
template<class T, std::size_t E, class U, std::size_t N>
|
||||
struct span_copyable {
|
||||
static constexpr bool value = (N == boost::dynamic_extent ||
|
||||
span_capacity<E, N>::value) && span_convertible<U, T>::value;
|
||||
};
|
||||
|
||||
template<std::size_t E, std::size_t O>
|
||||
struct span_sub {
|
||||
static constexpr std::size_t value = E == boost::dynamic_extent ?
|
||||
boost::dynamic_extent : E - O;
|
||||
};
|
||||
|
||||
template<class T, std::size_t E>
|
||||
struct span_store {
|
||||
constexpr span_store(T* p_, std::size_t) noexcept
|
||||
: p(p_) { }
|
||||
static constexpr std::size_t n = E;
|
||||
T* p;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct span_store<T, boost::dynamic_extent> {
|
||||
constexpr span_store(T* p_, std::size_t n_) noexcept
|
||||
: p(p_)
|
||||
, n(n_) { }
|
||||
T* p;
|
||||
std::size_t n;
|
||||
};
|
||||
|
||||
template<class T, std::size_t E>
|
||||
struct span_bytes {
|
||||
static constexpr std::size_t value = sizeof(T) * E;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct span_bytes<T, boost::dynamic_extent> {
|
||||
static constexpr std::size_t value = boost::dynamic_extent;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class T, std::size_t E>
|
||||
class span {
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef typename std::remove_cv<T>::type value_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef std::reverse_iterator<T*> reverse_iterator;
|
||||
typedef std::reverse_iterator<const T*> const_reverse_iterator;
|
||||
|
||||
static constexpr std::size_t extent = E;
|
||||
|
||||
template<std::size_t N = E,
|
||||
typename std::enable_if<N == dynamic_extent || N == 0, int>::type = 0>
|
||||
constexpr span() noexcept
|
||||
: s_(0, 0) { }
|
||||
|
||||
template<class I,
|
||||
typename std::enable_if<E == dynamic_extent &&
|
||||
detail::span_convertible<I, T>::value, int>::type = 0>
|
||||
constexpr span(I* f, size_type c)
|
||||
: s_(f, c) { }
|
||||
|
||||
template<class I,
|
||||
typename std::enable_if<E != dynamic_extent &&
|
||||
detail::span_convertible<I, T>::value, int>::type = 0>
|
||||
explicit constexpr span(I* f, size_type c)
|
||||
: s_(f, c) { }
|
||||
|
||||
template<class I, class L,
|
||||
typename std::enable_if<E == dynamic_extent &&
|
||||
detail::span_convertible<I, T>::value, int>::type = 0>
|
||||
constexpr span(I* f, L* l)
|
||||
: s_(f, l - f) { }
|
||||
|
||||
template<class I, class L,
|
||||
typename std::enable_if<E != dynamic_extent &&
|
||||
detail::span_convertible<I, T>::value, int>::type = 0>
|
||||
explicit constexpr span(I* f, L* l)
|
||||
: s_(f, l - f) { }
|
||||
|
||||
template<std::size_t N,
|
||||
typename std::enable_if<detail::span_capacity<E, N>::value,
|
||||
int>::type = 0>
|
||||
constexpr span(typename std::enable_if<true, T>::type (&a)[N]) noexcept
|
||||
: s_(a, N) { }
|
||||
|
||||
template<class U, std::size_t N,
|
||||
typename std::enable_if<detail::span_compatible<T, E, U, N>::value,
|
||||
int>::type = 0>
|
||||
constexpr span(std::array<U, N>& a) noexcept
|
||||
: s_(a.data(), N) { }
|
||||
|
||||
template<class U, std::size_t N,
|
||||
typename std::enable_if<detail::span_compatible<T, E, const U,
|
||||
N>::value, int>::type = 0>
|
||||
constexpr span(const std::array<U, N>& a) noexcept
|
||||
: s_(a.data(), N) { }
|
||||
|
||||
template<class R,
|
||||
typename std::enable_if<E == dynamic_extent &&
|
||||
detail::span_is_range<R, T>::value, int>::type = 0>
|
||||
constexpr span(R&& r) noexcept(noexcept(boost::data(r)) &&
|
||||
noexcept(r.size()))
|
||||
: s_(boost::data(r), r.size()) { }
|
||||
|
||||
template<class R,
|
||||
typename std::enable_if<E != dynamic_extent &&
|
||||
detail::span_is_range<R, T>::value, int>::type = 0>
|
||||
explicit constexpr span(R&& r) noexcept(noexcept(boost::data(r)) &&
|
||||
noexcept(r.size()))
|
||||
: s_(boost::data(r), r.size()) { }
|
||||
|
||||
template<class U, std::size_t N,
|
||||
typename std::enable_if<detail::span_implicit<E, N>::value &&
|
||||
detail::span_copyable<T, E, U, N>::value, int>::type = 0>
|
||||
constexpr span(const span<U, N>& s) noexcept
|
||||
: s_(s.data(), s.size()) { }
|
||||
|
||||
template<class U, std::size_t N,
|
||||
typename std::enable_if<!detail::span_implicit<E, N>::value &&
|
||||
detail::span_copyable<T, E, U, N>::value, int>::type = 0>
|
||||
explicit constexpr span(const span<U, N>& s) noexcept
|
||||
: s_(s.data(), s.size()) { }
|
||||
|
||||
template<std::size_t C>
|
||||
constexpr span<T, C> first() const {
|
||||
static_assert(C <= E, "Count <= Extent");
|
||||
return span<T, C>(s_.p, C);
|
||||
}
|
||||
|
||||
template<std::size_t C>
|
||||
constexpr span<T, C> last() const {
|
||||
static_assert(C <= E, "Count <= Extent");
|
||||
return span<T, C>(s_.p + (s_.n - C), C);
|
||||
}
|
||||
|
||||
template<std::size_t O, std::size_t C = dynamic_extent>
|
||||
constexpr typename std::enable_if<C == dynamic_extent,
|
||||
span<T, detail::span_sub<E, O>::value> >::type subspan() const {
|
||||
static_assert(O <= E, "Offset <= Extent");
|
||||
return span<T, detail::span_sub<E, O>::value>(s_.p + O, s_.n - O);
|
||||
}
|
||||
|
||||
template<std::size_t O, std::size_t C = dynamic_extent>
|
||||
constexpr typename std::enable_if<C != dynamic_extent,
|
||||
span<T, C> >::type subspan() const {
|
||||
static_assert(O <= E && C <= E - O,
|
||||
"Offset <= Extent && Count <= Extent - Offset");
|
||||
return span<T, C>(s_.p + O, C);
|
||||
}
|
||||
|
||||
constexpr span<T, dynamic_extent> first(size_type c) const {
|
||||
return BOOST_CORE_DETAIL_ASSERT(c <= size()),
|
||||
span<T, dynamic_extent>(s_.p, c);
|
||||
}
|
||||
|
||||
constexpr span<T, dynamic_extent> last(size_type c) const {
|
||||
return BOOST_CORE_DETAIL_ASSERT(c <= size()),
|
||||
span<T, dynamic_extent>(s_.p + (s_.n - c), c);
|
||||
}
|
||||
|
||||
constexpr span<T, dynamic_extent> subspan(size_type o,
|
||||
size_type c = dynamic_extent) const {
|
||||
return BOOST_CORE_DETAIL_ASSERT(o <= size() &&
|
||||
(c == dynamic_extent || c + o <= size())),
|
||||
span<T, dynamic_extent>(s_.p + o,
|
||||
c == dynamic_extent ? s_.n - o : c);
|
||||
}
|
||||
|
||||
constexpr size_type size() const noexcept {
|
||||
return s_.n;
|
||||
}
|
||||
|
||||
constexpr size_type size_bytes() const noexcept {
|
||||
return s_.n * sizeof(T);
|
||||
}
|
||||
|
||||
constexpr bool empty() const noexcept {
|
||||
return s_.n == 0;
|
||||
}
|
||||
|
||||
constexpr reference operator[](size_type i) const {
|
||||
return BOOST_CORE_DETAIL_ASSERT(i < size()), s_.p[i];
|
||||
}
|
||||
|
||||
constexpr reference front() const {
|
||||
return BOOST_CORE_DETAIL_ASSERT(!empty()), *s_.p;
|
||||
}
|
||||
|
||||
constexpr reference back() const {
|
||||
return BOOST_CORE_DETAIL_ASSERT(!empty()), s_.p[s_.n - 1];
|
||||
}
|
||||
|
||||
constexpr pointer data() const noexcept {
|
||||
return s_.p;
|
||||
}
|
||||
|
||||
constexpr iterator begin() const noexcept {
|
||||
return s_.p;
|
||||
}
|
||||
|
||||
constexpr iterator end() const noexcept {
|
||||
return s_.p + s_.n;
|
||||
}
|
||||
|
||||
constexpr reverse_iterator rbegin() const noexcept {
|
||||
return reverse_iterator(s_.p + s_.n);
|
||||
}
|
||||
|
||||
constexpr reverse_iterator rend() const noexcept {
|
||||
return reverse_iterator(s_.p);
|
||||
}
|
||||
|
||||
constexpr const_iterator cbegin() const noexcept {
|
||||
return s_.p;
|
||||
}
|
||||
|
||||
constexpr const_iterator cend() const noexcept {
|
||||
return s_.p + s_.n;
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator crbegin() const noexcept {
|
||||
return const_reverse_iterator(s_.p + s_.n);
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator crend() const noexcept {
|
||||
return const_reverse_iterator(s_.p);
|
||||
}
|
||||
|
||||
private:
|
||||
detail::span_store<T, E> s_;
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
|
||||
template<class T, std::size_t E>
|
||||
constexpr std::size_t span<T, E>::extent;
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template<class I, class L>
|
||||
span(I*, L) -> span<I>;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
span(T(&)[N]) -> span<T, N>;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
span(std::array<T, N>&) -> span<T, N>;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
span(const std::array<T, N>&) -> span<const T, N>;
|
||||
|
||||
template<class R>
|
||||
span(R&&) -> span<typename detail::span_data<R>::type>;
|
||||
|
||||
template<class T, std::size_t E>
|
||||
span(span<T, E>) -> span<T, E>;
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_lib_byte
|
||||
template<class T, std::size_t E>
|
||||
inline span<const std::byte, detail::span_bytes<T, E>::value>
|
||||
as_bytes(span<T, E> s) noexcept
|
||||
{
|
||||
return span<const std::byte, detail::span_bytes<T,
|
||||
E>::value>(reinterpret_cast<const std::byte*>(s.data()),
|
||||
s.size_bytes());
|
||||
}
|
||||
|
||||
template<class T, std::size_t E>
|
||||
inline typename std::enable_if<!std::is_const<T>::value,
|
||||
span<std::byte, detail::span_bytes<T, E>::value> >::type
|
||||
as_writable_bytes(span<T, E> s) noexcept
|
||||
{
|
||||
return span<std::byte, detail::span_bytes<T,
|
||||
E>::value>(reinterpret_cast<std::byte*>(s.data()), s.size_bytes());
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
@ -10,58 +10,31 @@
|
||||
#define BOOST_CORE_SWAP_HPP
|
||||
|
||||
// Note: the implementation of this utility contains various workarounds:
|
||||
// - swap_impl is put outside the boost namespace, to avoid infinite
|
||||
// recursion (causing stack overflow) when swapping objects of a primitive
|
||||
// type.
|
||||
// - swap_impl has a using-directive, rather than a using-declaration,
|
||||
// because some compilers (including MSVC 7.1, Borland 5.9.3, and
|
||||
// Intel 8.1) don't do argument-dependent lookup when it has a
|
||||
// using-declaration instead.
|
||||
// - boost::swap has two template arguments, instead of one, to
|
||||
// avoid ambiguity when swapping objects of a Boost type that does
|
||||
// not have its own boost::swap overload.
|
||||
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <utility> //for std::swap (C++11)
|
||||
#include <algorithm> //for std::swap (C++98)
|
||||
#include <cstddef> //for std::size_t
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
#include <boost/core/invoke_swap.hpp>
|
||||
|
||||
namespace boost_swap_impl
|
||||
{
|
||||
// we can't use type_traits here
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
template<class T> struct is_const { enum _vt { value = 0 }; };
|
||||
template<class T> struct is_const<T const> { enum _vt { value = 1 }; };
|
||||
|
||||
template<class T>
|
||||
BOOST_GPU_ENABLED
|
||||
void swap_impl(T& left, T& right)
|
||||
{
|
||||
using namespace std;//use std::swap if argument dependent lookup fails
|
||||
swap(left,right);
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
BOOST_GPU_ENABLED
|
||||
void swap_impl(T (& left)[N], T (& right)[N])
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
::boost_swap_impl::swap_impl(left[i], right[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_HEADER_DEPRECATED("boost/core/invoke_swap.hpp")
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<class T1, class T2>
|
||||
BOOST_GPU_ENABLED
|
||||
typename enable_if_c< !boost_swap_impl::is_const<T1>::value && !boost_swap_impl::is_const<T2>::value >::type
|
||||
BOOST_DEPRECATED("This function is deprecated, use boost::core::invoke_swap instead.")
|
||||
inline typename enable_if_c< !boost_swap_impl::is_const<T1>::value && !boost_swap_impl::is_const<T2>::value >::type
|
||||
swap(T1& left, T2& right)
|
||||
{
|
||||
::boost_swap_impl::swap_impl(left, right);
|
||||
boost::core::invoke_swap(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // BOOST_CORE_SWAP_HPP
|
||||
|
1186
include/boost/core/type_name.hpp
Normal file
1186
include/boost/core/type_name.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2018.
|
||||
* Copyright Andrey Semashev 2018 - 2020.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -26,9 +26,24 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Visual Studio 14 supports N4152 std::uncaught_exceptions()
|
||||
#if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411) || \
|
||||
(defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||
#if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411)
|
||||
#if defined(__APPLE__)
|
||||
#include <Availability.h>
|
||||
// Apple systems only support std::uncaught_exceptions starting with specific versions:
|
||||
// - Mac OS >= 10.12
|
||||
// - iOS >= 10.0
|
||||
// - tvOS >= 10.0
|
||||
// - watchOS >= 3.0
|
||||
// https://github.com/boostorg/core/issues/80
|
||||
#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || \
|
||||
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
|
||||
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
|
||||
#endif
|
||||
#else
|
||||
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
|
||||
#endif // defined(__APPLE__)
|
||||
// Visual Studio 14.0 supports N4152 std::uncaught_exceptions() but doesn't define __cpp_lib_uncaught_exceptions
|
||||
#elif (defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
@ -46,7 +61,11 @@
|
||||
#if defined(BOOST_CORE_HAS_CXXABI_H)
|
||||
// MinGW GCC 4.4 seem to not work the same way the newer GCC versions do. As a result, __cxa_get_globals based implementation will always return 0.
|
||||
// Just disable it for now and fall back to std::uncaught_exception().
|
||||
#if !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405))
|
||||
// On AIX, xlclang++ does have cxxabi.h but doesn't have __cxa_get_globals (https://github.com/boostorg/core/issues/78).
|
||||
#if !( \
|
||||
(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405)) || \
|
||||
defined(__ibmxl__) \
|
||||
)
|
||||
#include <cxxabi.h>
|
||||
#include <cstring>
|
||||
#define BOOST_CORE_HAS_CXA_GET_GLOBALS
|
||||
@ -76,7 +95,7 @@ extern "C" __cxa_eh_globals* __cxa_get_globals() BOOST_NOEXCEPT_OR_NOTHROW __att
|
||||
#endif
|
||||
} // namespace __cxxabiv1
|
||||
#endif
|
||||
#endif // !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405))
|
||||
#endif
|
||||
#endif // defined(BOOST_CORE_HAS_CXXABI_H)
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
|
88
include/boost/core/verbose_terminate_handler.hpp
Normal file
88
include/boost/core/verbose_terminate_handler.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
|
||||
#define BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <exception>
|
||||
#include <typeinfo>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
BOOST_NORETURN inline void verbose_terminate_handler()
|
||||
{
|
||||
std::set_terminate( 0 );
|
||||
|
||||
#if defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
std::fputs( "std::terminate called with exceptions disabled\n", stderr );
|
||||
|
||||
#else
|
||||
|
||||
try
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch( std::exception const& x )
|
||||
{
|
||||
#if defined(BOOST_NO_RTTI)
|
||||
|
||||
char const * typeid_name = "unknown (RTTI is disabled)";
|
||||
|
||||
#else
|
||||
|
||||
char const * typeid_name = typeid( x ).name();
|
||||
|
||||
boost::core::scoped_demangled_name typeid_demangled_name( typeid_name );
|
||||
|
||||
if( typeid_demangled_name.get() != 0 )
|
||||
{
|
||||
typeid_name = typeid_demangled_name.get();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
std::fprintf( stderr,
|
||||
"std::terminate called after throwing an exception:\n\n"
|
||||
" type: %s\n"
|
||||
" what(): %s\n"
|
||||
" location: %s:%lu:%lu in function '%s'\n",
|
||||
|
||||
typeid_name,
|
||||
x.what(),
|
||||
loc.file_name(), static_cast<unsigned long>( loc.line() ),
|
||||
static_cast<unsigned long>( loc.column() ), loc.function_name()
|
||||
);
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
std::fputs( "std::terminate called after throwing an unknown exception\n", stderr );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::fflush( stdout );
|
||||
std::abort();
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
|
12
include/boost/core/yield_primitives.hpp
Normal file
12
include/boost/core/yield_primitives.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED
|
||||
#define BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/detail/sp_thread_pause.hpp>
|
||||
#include <boost/core/detail/sp_thread_yield.hpp>
|
||||
#include <boost/core/detail/sp_thread_sleep.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user