mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-10-04 19:51:02 +02:00
Compare commits
1039 Commits
boost-1.23
...
boost-1.62
Author | SHA1 | Date | |
---|---|---|---|
|
f3279d24b4 | ||
|
c87b6e8af8 | ||
|
aaded4f85c | ||
|
eb1a002e34 | ||
|
3304a56101 | ||
|
181f38682f | ||
|
5b1a8412c3 | ||
|
e52905cf3c | ||
|
b7f99ceba6 | ||
|
a7ade6f062 | ||
|
097d2e9bf9 | ||
|
d44a78d671 | ||
|
582eb63cb3 | ||
|
181b449a57 | ||
|
da8de3e95b | ||
|
6c27833099 | ||
|
83e6e00456 | ||
|
522f6c1869 | ||
|
cd8de9d4a6 | ||
|
e26542272d | ||
|
e13beef5df | ||
|
8298952a12 | ||
|
821925c536 | ||
|
427124543b | ||
|
46f00ea993 | ||
|
4473bf8ec2 | ||
|
7a7ac4512e | ||
|
38b6334e36 | ||
|
7af503d3bb | ||
|
4db7219c32 | ||
|
3f17244225 | ||
|
ca93749614 | ||
|
05d5a4e9a0 | ||
|
970a179ac2 | ||
|
a06123eb87 | ||
|
fd543d3292 | ||
|
df90496583 | ||
|
20ead68473 | ||
|
79cde147c9 | ||
|
abbe975e8f | ||
|
8ba0730686 | ||
|
686efe100b | ||
|
acb880d8c2 | ||
|
1712b87cb6 | ||
|
f8943703f8 | ||
|
a42dda0af4 | ||
|
9b9b6d3ca6 | ||
|
d875a68ceb | ||
|
8cb2c56556 | ||
|
290fe82a43 | ||
|
94824c807f | ||
|
334654de06 | ||
|
0ab0e6eecc | ||
|
effc9f73d6 | ||
|
99762e7dde | ||
|
add539142b | ||
|
e067fd2cfd | ||
|
212528860a | ||
|
711c36958a | ||
|
7104e7dc7e | ||
|
254bda34b7 | ||
|
3fd53ced83 | ||
|
75de3dbcf1 | ||
|
7faec4265b | ||
|
c81d0806e4 | ||
|
a74329794c | ||
|
71756350d9 | ||
|
f65c57d9d2 | ||
|
b1fc261fe6 | ||
|
aedcf3ccda | ||
|
a1a5999a38 | ||
|
8afd3bee69 | ||
|
2a56c73924 | ||
|
720ce12a25 | ||
|
2be09db523 | ||
|
de10be8560 | ||
|
7b71068b52 | ||
|
6b562cb5b1 | ||
|
3d2c230623 | ||
|
553c7994ba | ||
|
280aadfcdb | ||
|
59ac922a1c | ||
|
8de3e84021 | ||
|
bd4f9c239a | ||
|
528195233b | ||
|
8c49f5a637 | ||
|
0bab2cc658 | ||
|
88f0a98d71 | ||
|
96d82e0275 | ||
|
40387ef654 | ||
|
d28b0d07fc | ||
|
1c83d65701 | ||
|
1d41a328f7 | ||
|
b1beb11a45 | ||
|
bf3e9cc7af | ||
|
506239bef5 | ||
|
d6841e6d71 | ||
|
56ae9f86c1 | ||
|
1a74757cfa | ||
|
07e222217b | ||
|
71c9165119 | ||
|
f32669400c | ||
|
b550e028f5 | ||
|
ed2eaddc5d | ||
|
d523c3423e | ||
|
1968d17d2f | ||
|
e1e99c5ba3 | ||
|
d586469d60 | ||
|
fbb851097f | ||
|
75add10b1d | ||
|
71b2f87e35 | ||
|
c759321782 | ||
|
3e625c07e8 | ||
|
7ff1c65494 | ||
|
75cab39801 | ||
|
38cb523713 | ||
|
5f1d4eae4f | ||
|
adc0cdddff | ||
|
dcfa031de7 | ||
|
8c9e8b5556 | ||
|
d9333e5375 | ||
|
3d279e6c6d | ||
|
c003fba3a0 | ||
|
0c29e86728 | ||
|
016af907bd | ||
|
0337743c8c | ||
|
208bfd78f9 | ||
|
2c32bf91b7 | ||
|
b7ee788845 | ||
|
a56378ee35 | ||
|
443302306e | ||
|
f5402a937e | ||
|
fe04bea979 | ||
|
8fbb5e9e7f | ||
|
0401afc106 | ||
|
b69ca7aaa5 | ||
|
dffbf7c931 | ||
|
5dabdf635c | ||
|
3dbde36076 | ||
|
97a9aac5f0 | ||
|
bd5b684fd3 | ||
|
6ede4ec4c6 | ||
|
aab1328e06 | ||
|
451c71c1bd | ||
|
6341b8802a | ||
|
e274885fd2 | ||
|
82fe5f5095 | ||
|
8c50214e3f | ||
|
21198d07fd | ||
|
b4c8cf3958 | ||
|
77aeaee7a7 | ||
|
677a0777d2 | ||
|
7c7250379b | ||
|
142eb95986 | ||
|
d9f24f882e | ||
|
0fd3947e19 | ||
|
43bc30e576 | ||
|
e0ec2a0aaa | ||
|
5320981cbb | ||
|
d676bac36a | ||
|
ec1c6ed414 | ||
|
ce36b11fd5 | ||
|
eee70bdcab | ||
|
97eed20d9b | ||
|
6b6b63ef37 | ||
|
1bdabdb96b | ||
|
0876e67ac7 | ||
|
fdcb2572a3 | ||
|
71d99e89e9 | ||
|
2dc506f4bc | ||
|
7161dc5842 | ||
|
ec97270c01 | ||
|
b7a759f00f | ||
|
4f2392ffa5 | ||
|
80a06c8883 | ||
|
d0a458616f | ||
|
def81b1941 | ||
|
4f276715ce | ||
|
a47bbfe95c | ||
|
90fe855f1b | ||
|
991436303d | ||
|
b274ed4cc3 | ||
|
870a989fcf | ||
|
5f7a5a5912 | ||
|
82db88f4fa | ||
|
c8df85434e | ||
|
68517b43bd | ||
|
72ac0e8bfd | ||
|
6c7578e206 | ||
|
3149446fe8 | ||
|
b11d734f73 | ||
|
6f5f8babf4 | ||
|
7d7f32c3a9 | ||
|
cb697fe9cb | ||
|
8422135bf2 | ||
|
fd60899dfb | ||
|
a11ab16010 | ||
|
9b9cad3f5b | ||
|
7ce5b6b2a9 | ||
|
7e3ae44bc2 | ||
|
57dc400fbf | ||
|
5f485c2952 | ||
|
260af64027 | ||
|
f837c7f56c | ||
|
54fb49a5be | ||
|
c23bd41c44 | ||
|
a64cc5c41c | ||
|
e1f170cd49 | ||
|
52a5c422a1 | ||
|
d46e3c7cbd | ||
|
5008957bd0 | ||
|
6d73b4aa54 | ||
|
540149f019 | ||
|
9f5822f427 | ||
|
d229ae870c | ||
|
3ac6dbbf08 | ||
|
af5141d492 | ||
|
975d04ac62 | ||
|
90e74511f7 | ||
|
f27b780724 | ||
|
51ab46a07d | ||
|
e8595a05af | ||
|
154a274916 | ||
|
2b033ce05d | ||
|
63a05a3576 | ||
|
aede0039bf | ||
|
72e5fb6fd7 | ||
|
f91e7e9ce7 | ||
|
7fef3bb40b | ||
|
ad658fa5ec | ||
|
83b3b703e0 | ||
|
7806737b52 | ||
|
87e5debdc2 | ||
|
db78d9b2be | ||
|
630e4f49f3 | ||
|
a68db557e8 | ||
|
4de3f36839 | ||
|
4e46cb0609 | ||
|
73153d5797 | ||
|
d7fa365843 | ||
|
6e0ee30543 | ||
|
fed15ad8c5 | ||
|
bba3b446bd | ||
|
4c8a558982 | ||
|
a41b81f1c8 | ||
|
c103ace77a | ||
|
04f456f86d | ||
|
3a188af8d6 | ||
|
b701ed0225 | ||
|
5e9bb19688 | ||
|
a4f853bfbc | ||
|
832ed079b9 | ||
|
d9b29beebe | ||
|
182452e057 | ||
|
5f69684c8f | ||
|
70ffd2921f | ||
|
00aee2c7dc | ||
|
85d8056368 | ||
|
106832df66 | ||
|
2549b818c5 | ||
|
be06392771 | ||
|
56b0853887 | ||
|
f5e6e4063e | ||
|
8767b9580e | ||
|
0e6ddb843e | ||
|
14be9eb90f | ||
|
fa91b7d020 | ||
|
382fb54a52 | ||
|
e4f24e4d3d | ||
|
7d1c527ac0 | ||
|
fc20a29c99 | ||
|
0dc1faa6d3 | ||
|
7b9354fcf3 | ||
|
a7d96b4762 | ||
|
6eefc6bf81 | ||
|
172afff6ca | ||
|
9355404d10 | ||
|
d61e675caf | ||
|
240c66e633 | ||
|
6df3a0295e | ||
|
e497aec58a | ||
|
2d56e85174 | ||
|
579b347267 | ||
|
82e178f043 | ||
|
3178d38137 | ||
|
46d119c385 | ||
|
e39fcad839 | ||
|
e5950adc43 | ||
|
de6dc3a26e | ||
|
06c4dacaf2 | ||
|
72095a4804 | ||
|
dcc1713c59 | ||
|
32a28ec462 | ||
|
f6d5257597 | ||
|
ef817e91d2 | ||
|
43b43aa83a | ||
|
d3a549e93a | ||
|
e8be24c003 | ||
|
c55ffa1cab | ||
|
66f34142be | ||
|
63834f7233 | ||
|
049d0698b7 | ||
|
5ba3312519 | ||
|
bb700870c0 | ||
|
6a218a5ef2 | ||
|
e36689bd5e | ||
|
1c070b3a32 | ||
|
647f67aabf | ||
|
c14369aac9 | ||
|
7ab4f6ce92 | ||
|
bbf0245248 | ||
|
619b168614 | ||
|
4ba8d879f1 | ||
|
c28bef2e9b | ||
|
5f0155cca6 | ||
|
db542de908 | ||
|
5fc6fe474b | ||
|
d42ce87557 | ||
|
67f5e9825e | ||
|
fd52dbc411 | ||
|
6e269872df | ||
|
ecceb710de | ||
|
9863467152 | ||
|
b306c9751f | ||
|
6b0d96af96 | ||
|
c03bfd0b4d | ||
|
8093967da7 | ||
|
7a4ad75f5d | ||
|
f390d9e265 | ||
|
ea22982865 | ||
|
09e77bc8df | ||
|
b3f2ebedbc | ||
|
1209531fe0 | ||
|
6c2ed927e4 | ||
|
7a733263da | ||
|
08e5894510 | ||
|
3551d17566 | ||
|
32fe0b8f26 | ||
|
2d3cc0db7d | ||
|
188602581d | ||
|
88c2baa20b | ||
|
1adf546ddb | ||
|
5e5ff387fa | ||
|
ea55019260 | ||
|
500913db6d | ||
|
19283a3548 | ||
|
cfd4152291 | ||
|
f5adfb0963 | ||
|
8597433028 | ||
|
4da0e2b7fc | ||
|
2346941b15 | ||
|
39ff002d2e | ||
|
fceea2e584 | ||
|
b17205ded7 | ||
|
d74c09dd5a | ||
|
97d32745aa | ||
|
c7b6e56b30 | ||
|
7835914d83 | ||
|
98b92fa83a | ||
|
392885a56a | ||
|
b4594eab3b | ||
|
ddfcc5f417 | ||
|
3f458c68f4 | ||
|
79b229adcd | ||
|
94b6487ca1 | ||
|
cf769b94a7 | ||
|
215771c83d | ||
|
2805ae9362 | ||
|
7adb1cc1ec | ||
|
da9524d637 | ||
|
6b2556edfb | ||
|
cb0797acf0 | ||
|
e8103f9774 | ||
|
71eb435412 | ||
|
4a2dad1574 | ||
|
babc72757d | ||
|
c19cbc1892 | ||
|
d065e4d971 | ||
|
777b86a661 | ||
|
aae5440854 | ||
|
227d2e3255 | ||
|
8bf183b373 | ||
|
5017da2514 | ||
|
3b0b10d06d | ||
|
25e11b20d3 | ||
|
fa513340d7 | ||
|
0e90213746 | ||
|
980070e63f | ||
|
5bdde37414 | ||
|
2aaa913b11 | ||
|
58a46f4e55 | ||
|
8cc50a5ce9 | ||
|
2731957b5b | ||
|
fe06c120b9 | ||
|
c1f41aa925 | ||
|
ffa3327817 | ||
|
999c284109 | ||
|
d512eaaa0f | ||
|
730980f3ee | ||
|
3d50db11b9 | ||
|
aa7562c3e5 | ||
|
c57245d710 | ||
|
945c013a12 | ||
|
df544871d7 | ||
|
89190ca17e | ||
|
5d9312239c | ||
|
93b5cace12 | ||
|
e50c849ab3 | ||
|
dbea328b8b | ||
|
c06ba497a3 | ||
|
734b5d1354 | ||
|
0467af1b83 | ||
|
dc5406aa5a | ||
|
6e873de0fa | ||
|
322bcd7efa | ||
|
bb72e0a092 | ||
|
d8eb2fc105 | ||
|
e7d3987cfb | ||
|
6662ae7242 | ||
|
2ba7b6b99b | ||
|
a30e291022 | ||
|
0b6cab9f2f | ||
|
8c15401ea7 | ||
|
03ae5cdbc6 | ||
|
0c22e55f3e | ||
|
10dcb8db7c | ||
|
f2d4b67a48 | ||
|
16084637a6 | ||
|
3e447c919c | ||
|
b0f72d7b3d | ||
|
4c98df7c57 | ||
|
c2048732d8 | ||
|
5979c1d4bd | ||
|
1029ae0ea5 | ||
|
27a312228c | ||
|
3090f6f4af | ||
|
2c29f1e5a9 | ||
|
40073ef64f | ||
|
b9970eda45 | ||
|
df364f37f2 | ||
|
9147489b4c | ||
|
33ba2c4722 | ||
|
d1348ea05e | ||
|
faf212f4aa | ||
|
57a5441ebf | ||
|
90db9a6435 | ||
|
017ab7e2ee | ||
|
1c208ad3ea | ||
|
5fc9bf5bc5 | ||
|
c846d230f0 | ||
|
e4cb5e131f | ||
|
fbe4ddf4a2 | ||
|
288fb7efcf | ||
|
7b097467d6 | ||
|
9d9e6350f2 | ||
|
7cb040edb0 | ||
|
d6ac116b71 | ||
|
7e9664396a | ||
|
b4b415553c | ||
|
f76a8d95d8 | ||
|
8abc8889d1 | ||
|
c5b47e2136 | ||
|
7c0815c567 | ||
|
210288f02e | ||
|
cf7b6904e8 | ||
|
b978919dd1 | ||
|
1086aff971 | ||
|
445e8d1728 | ||
|
545745d649 | ||
|
634866c28a | ||
|
b18b47770d | ||
|
69aa01ec00 | ||
|
e3d2f2ee6b | ||
|
593093e46d | ||
|
9196247dea | ||
|
53d5d086ea | ||
|
1426b0bbdd | ||
|
4fabf9b352 | ||
|
a2fc6e12da | ||
|
c3b51e201b | ||
|
d71cc6ab08 | ||
|
825786d59a | ||
|
37f10d500d | ||
|
0d77fd0678 | ||
|
6ca6d3ce6f | ||
|
cfc82854d3 | ||
|
3c84388186 | ||
|
a46d405778 | ||
|
2e53b1eb38 | ||
|
b9d77d877e | ||
|
1f50e3abe4 | ||
|
37c9a235a5 | ||
|
7083e76666 | ||
|
7aac2f3263 | ||
|
458dffdab9 | ||
|
697f338510 | ||
|
f7919f0b9f | ||
|
f4386409d9 | ||
|
ae34be773f | ||
|
1b91c1dbea | ||
|
ba349679f3 | ||
|
577528812a | ||
|
e78efdbb96 | ||
|
a3b84f8586 | ||
|
3824a6b156 | ||
|
b0fd8a6b08 | ||
|
4f5062004a | ||
|
f040bed751 | ||
|
2f8945a885 | ||
|
2bd0778778 | ||
|
eec640bfd7 | ||
|
754fd941ee | ||
|
b691be0af9 | ||
|
fa597b877e | ||
|
d0a9d76494 | ||
|
979e76b7e0 | ||
|
c97eebabf7 | ||
|
030a848c5f | ||
|
18bfaea996 | ||
|
502de325ee | ||
|
9f49538b37 | ||
|
2ee5eb70f3 | ||
|
32eb028e13 | ||
|
e824e23ec2 | ||
|
e94f64039d | ||
|
63b17c24ea | ||
|
f5cc79f58d | ||
|
8a421c2098 | ||
|
28d7e348c1 | ||
|
5fa1cbf6e1 | ||
|
fc12543814 | ||
|
9f30442d1e | ||
|
a4293f9dfa | ||
|
4b4a62513f | ||
|
0368a37fde | ||
|
28de0cb1e3 | ||
|
3dacec8e1d | ||
|
a1b4fc8d95 | ||
|
5758e51948 | ||
|
287d329276 | ||
|
d34d638998 | ||
|
6f2bdddfa0 | ||
|
9227371881 | ||
|
e88dd9fc77 | ||
|
77971c6ff5 | ||
|
1742c37942 | ||
|
fa3c56747d | ||
|
fbc6919eae | ||
|
31e06b4a1d | ||
|
dc3ffc5f4b | ||
|
0610947c4a | ||
|
22f1b092c9 | ||
|
9c55fbc6c2 | ||
|
5a2771e585 | ||
|
dad59f3325 | ||
|
bad394b1e9 | ||
|
f93110620a | ||
|
6be1e3fceb | ||
|
cf91287732 | ||
|
68c939ec5a | ||
|
a378c8c278 | ||
|
905a3711db | ||
|
ed32efcc51 | ||
|
eb0ff40d62 | ||
|
ad1b344405 | ||
|
0da6902267 | ||
|
10f6ff8b77 | ||
|
13f91c15f0 | ||
|
a2c5208b8e | ||
|
55583ac749 | ||
|
c40b306647 | ||
|
d9b9921d23 | ||
|
6f91ea87c3 | ||
|
ed79000ea8 | ||
|
6e804e64b8 | ||
|
395766e2d3 | ||
|
774332f85a | ||
|
f5990cab65 | ||
|
6175baf858 | ||
|
2fb567b3f2 | ||
|
2b25579338 | ||
|
a97cd2d0cc | ||
|
e3b9389a24 | ||
|
6ba78f76f6 | ||
|
8c7954a53a | ||
|
556b9fe563 | ||
|
77ab953171 | ||
|
991b02b03e | ||
|
31d0c48f18 | ||
|
1b49f08cb8 | ||
|
034c12d244 | ||
|
f884c53bd6 | ||
|
07b4c17980 | ||
|
1bc4f16ff8 | ||
|
774a8d330c | ||
|
0fd94d6d56 | ||
|
866590ee97 | ||
|
2a92df56f2 | ||
|
a9cd84f43d | ||
|
366472fc35 | ||
|
2bfe13c9c4 | ||
|
83e2510ce5 | ||
|
31685fe551 | ||
|
05e050abe0 | ||
|
d261079616 | ||
|
d52878df88 | ||
|
4b0490c0ae | ||
|
2f1b1acc7a | ||
|
f0f9f72be6 | ||
|
efdc390bc9 | ||
|
d13f1d8694 | ||
|
83c43617af | ||
|
da323af72d | ||
|
0c4aaef77c | ||
|
440fcb7ba0 | ||
|
18a6c1add8 | ||
|
357d3c4d54 | ||
|
4bb747fb27 | ||
|
f13591ef2b | ||
|
e3422efec6 | ||
|
a01e4c3f83 | ||
|
6f8dc5923c | ||
|
7dc6b3d810 | ||
|
2251b1d2df | ||
|
8b3907ae81 | ||
|
77f2d3f614 | ||
|
93545d5cf2 | ||
|
9e92c6354c | ||
|
e12ed6864b | ||
|
b541145a60 | ||
|
ca344809ba | ||
|
7802c695ef | ||
|
71fa2cd658 | ||
|
04be979670 | ||
|
35f2af947c | ||
|
3a578ac7c1 | ||
|
9365853fde | ||
|
16828c9c0a | ||
|
2fe899cdfe | ||
|
b45d011d5a | ||
|
4094c23537 | ||
|
f85a1bf406 | ||
|
dbd62686a3 | ||
|
e4f638025c | ||
|
d8296b3933 | ||
|
b4885a1dd6 | ||
|
748b1baee8 | ||
|
4880292c07 | ||
|
6b25c57712 | ||
|
373c52efa3 | ||
|
acb6824ef7 | ||
|
316d00c3fc | ||
|
515be965bd | ||
|
6ef32e1627 | ||
|
2452705117 | ||
|
bb076d67e6 | ||
|
b08789b784 | ||
|
5df69a8946 | ||
|
dc6a8f0696 | ||
|
af7d4fabad | ||
|
d17a096407 | ||
|
d7448b5746 | ||
|
f22516d650 | ||
|
b30aa1468a | ||
|
5b17f88f0e | ||
|
1c2d780f9e | ||
|
2eb3991630 | ||
|
3a4dc43924 | ||
|
a055d9829e | ||
|
f596092bac | ||
|
4ba016d29e | ||
|
7ca6d86bdc | ||
|
b2a3c9e59d | ||
|
60ae24f4ae | ||
|
dba6ebbb01 | ||
|
d2194e3b24 | ||
|
5ab6b24856 | ||
|
e6f6ec9fa3 | ||
|
f854829d86 | ||
|
7b5beeedde | ||
|
9e41d1f194 | ||
|
f49a2fb1e1 | ||
|
87c6b6b403 | ||
|
9db307eda5 | ||
|
5a85c1f0f2 | ||
|
f5ce4dbc4c | ||
|
b2354d0a5e | ||
|
e0ca42bb88 | ||
|
bca336bf35 | ||
|
6646d8acd2 | ||
|
c66f0aeecc | ||
|
ecb41cb150 | ||
|
ed8db8b5f2 | ||
|
4ba37fce95 | ||
|
94db735438 | ||
|
5b57eff9b8 | ||
|
f980da560a | ||
|
ffba68221b | ||
|
4d45e5b9b5 | ||
|
86d3f0aba7 | ||
|
66a25bd4a9 | ||
|
745dbedbaa | ||
|
26f83e75ef | ||
|
ce72827dc7 | ||
|
6e8f075d42 | ||
|
ae6c180be8 | ||
|
54e12d03fd | ||
|
469578e976 | ||
|
97118668e2 | ||
|
1c3813ce52 | ||
|
b440e85452 | ||
|
d889751bc0 | ||
|
0609322489 | ||
|
b215e34650 | ||
|
2f70e81b73 | ||
|
6284a1abef | ||
|
c464a07ab1 | ||
|
41d4167533 | ||
|
4a98c2931c | ||
|
75bc821afd | ||
|
ebc0af9147 | ||
|
db0969d97b | ||
|
39551bdc1a | ||
|
6412de1dd5 | ||
|
8d2f7fc5ef | ||
|
7c477960d3 | ||
|
7e5d7011e6 | ||
|
ffd73c39b3 | ||
|
4fcee64483 | ||
|
75cd88112c | ||
|
203764eb51 | ||
|
6e120f4bf1 | ||
|
747c9a1d3e | ||
|
7ce5b55f5c | ||
|
e38d0daaab | ||
|
f3e94d8ca0 | ||
|
c36e023162 | ||
|
00f744bf1e | ||
|
24d1e6f8dd | ||
|
ae0a48d544 | ||
|
e427716dc2 | ||
|
8c256502cc | ||
|
a86b2f7fbf | ||
|
a196f39cd0 | ||
|
90b5a3736a | ||
|
2d25f8f036 | ||
|
3771707bb7 | ||
|
239bb6d966 | ||
|
25ca855127 | ||
|
0127c06692 | ||
|
9edd3beebc | ||
|
92a027fbeb | ||
|
7880720bc1 | ||
|
235994873f | ||
|
7bfddbccf6 | ||
|
c6a4e93a05 | ||
|
ff7e027648 | ||
|
08f517b5b0 | ||
|
6b3f961542 | ||
|
0db2a88403 | ||
|
afc17037de | ||
|
0cee41d47e | ||
|
eb3d3464db | ||
|
8d2aeea3a8 | ||
|
675d09723a | ||
|
24c23b8064 | ||
|
880c2e1062 | ||
|
357f57d147 | ||
|
8bacee46eb | ||
|
4e4ec29fc9 | ||
|
df1d8b27df | ||
|
76722e125f | ||
|
d24f6d3b97 | ||
|
6ab6b66601 | ||
|
559056c856 | ||
|
13c128f98f | ||
|
3ebc9b8f0b | ||
|
361a7c3fd0 | ||
|
faa675ad6a | ||
|
319836fe78 | ||
|
d0656015ad | ||
|
f1a9148a43 | ||
|
1942b64751 | ||
|
a0eb5daf75 | ||
|
6046a099ba | ||
|
e0ee037e2d | ||
|
13657c8bda | ||
|
52587aaa05 | ||
|
0669d41076 | ||
|
8f2beee8e9 | ||
|
3adfc7842c | ||
|
613e684b30 | ||
|
bfc0225cda | ||
|
a67e505cf5 | ||
|
adec862262 | ||
|
c6bf857f8b | ||
|
14024e2598 | ||
|
34953d8a45 | ||
|
09a0ba8c75 | ||
|
b0eb65b433 | ||
|
c830315dff | ||
|
b07447aa6e | ||
|
42a739b357 | ||
|
7d59d29ad1 | ||
|
5616a1a872 | ||
|
e5c1e12a66 | ||
|
8f317492ee | ||
|
c81be1e2e7 | ||
|
1bc58ea861 | ||
|
27be736b8f | ||
|
ef51f6a1de | ||
|
6b00a55542 | ||
|
858cefbfe8 | ||
|
c7abff0099 | ||
|
cb6cb636f7 | ||
|
366d2666d4 | ||
|
9c67a59d43 | ||
|
7361e476b8 | ||
|
e1bd18f6a6 | ||
|
1346982b80 | ||
|
c48f05dcb4 | ||
|
53cc52127b | ||
|
7fb399b3bb | ||
|
93d69af60a | ||
|
09c8685181 | ||
|
15d6b2aace | ||
|
feff6e40ea | ||
|
26a93f224e | ||
|
96f572b19b | ||
|
d6c4633e89 | ||
|
106a6d58d4 | ||
|
debd953d8f | ||
|
f2c5439644 | ||
|
b4ec0e90fb | ||
|
2d4eb92401 | ||
|
192970b3b8 | ||
|
7c36a640ae | ||
|
794de98cd1 | ||
|
dcdbaf1e57 | ||
|
6dbec7621d | ||
|
889cb6bee6 | ||
|
11cddbbb45 | ||
|
77c629b6e4 | ||
|
d091ee85c0 | ||
|
bc00d5fa1a | ||
|
e760759414 | ||
|
deab8ca1bb | ||
|
300f8f7b9a | ||
|
d7c841484a | ||
|
f4dce1cb88 | ||
|
b400d34bec | ||
|
8f0bdd48f8 | ||
|
6d6bcc7be9 | ||
|
851d87a1bb | ||
|
34f423f811 | ||
|
190893a1ce | ||
|
4244992d4d | ||
|
4b502993b5 | ||
|
a24ec3988a | ||
|
23f7532a9f | ||
|
a790191bc5 | ||
|
86e9a322ba | ||
|
98fa979aef | ||
|
be0267f9a3 | ||
|
44afc7e5cd | ||
|
d2c7febd26 | ||
|
ddf1f0fdcc | ||
|
cd41426fe9 | ||
|
89ea2156bc | ||
|
fabd6e5755 | ||
|
b60de38d28 | ||
|
2dbfc89d4e | ||
|
abb0d9e725 | ||
|
d030182e87 | ||
|
bd39e2eded | ||
|
d04757128c | ||
|
868062e81d | ||
|
6bd66fe054 | ||
|
c5bae28eeb | ||
|
78a47d7619 | ||
|
8eaf187dbd | ||
|
d36a215554 | ||
|
8448bbf0b9 | ||
|
1dee6e0229 | ||
|
e3f2329c14 | ||
|
3e616752c9 | ||
|
987a7d32fb | ||
|
fafd9a863b | ||
|
51e9783a21 | ||
|
eee96e8059 | ||
|
1ef2a5b059 | ||
|
c5f7c973d9 | ||
|
572a97d3c4 | ||
|
a3d87ff623 | ||
|
468f63261a | ||
|
e60c1f9b49 | ||
|
72bcb8ff46 | ||
|
12b1871136 | ||
|
9632464c45 | ||
|
1311731e24 | ||
|
980307a90a | ||
|
1f9908be69 | ||
|
0aaca2fffe | ||
|
5dd2c62132 | ||
|
fadc0716ce | ||
|
ea285b4231 | ||
|
8d6517484c | ||
|
66a8e8b3c1 | ||
|
c697e2ef21 | ||
|
2e53e2e5d7 | ||
|
8283ec826b | ||
|
e32b2adfda | ||
|
e555d33695 | ||
|
de68e6ed1e | ||
|
804b1483c7 | ||
|
4b200e9847 | ||
|
f34866e8a5 | ||
|
45c799f40c | ||
|
11a046f628 | ||
|
b632f1ef20 | ||
|
7f30268b10 | ||
|
7504eff5af | ||
|
8752c00ebf | ||
|
d0c5e83def | ||
|
f6b7ff4b34 | ||
|
2314f20c4e | ||
|
ff7410cad2 | ||
|
57c0ad44f3 | ||
|
ae60bcaffb | ||
|
f2f616a95c | ||
|
a8bb455df7 | ||
|
9dcbc46225 | ||
|
024f918b86 | ||
|
0f05f41306 | ||
|
4ea6decc7d | ||
|
f79b8cb7ae | ||
|
275cb77378 | ||
|
b916445dd8 | ||
|
c02fee7013 | ||
|
e77889679f | ||
|
b9dceb2340 | ||
|
e84eb3f1ba | ||
|
92999be436 | ||
|
bd4f575567 | ||
|
09016db3c3 | ||
|
c2ee5172b0 | ||
|
8436c4d271 | ||
|
a09c2e556f | ||
|
e650c7ff16 | ||
|
c06b4206f2 | ||
|
89435a6287 | ||
|
5328674c2d | ||
|
927fe73093 | ||
|
053aa108e3 | ||
|
b5e5c35696 | ||
|
77ad156c52 | ||
|
018c401e47 | ||
|
f586d3f83e | ||
|
3f0ebd4c71 | ||
|
33077bda71 | ||
|
547888d507 | ||
|
af6fe18c9d | ||
|
dca9628be3 | ||
|
d84fa738ef | ||
|
a322dc54dc | ||
|
951c2b7e83 | ||
|
23f68a5657 | ||
|
ecb0b4478b | ||
|
70255d46bb | ||
|
4653c3673b | ||
|
11eacab70e | ||
|
110c0021e2 | ||
|
4c5e355a0b | ||
|
fbc9028313 | ||
|
9b800d4f84 | ||
|
513752eee5 | ||
|
9eb1ba7e9f | ||
|
fb5b1a20d2 | ||
|
b89945d36a | ||
|
220f35a0f1 | ||
|
72f83165e0 | ||
|
c17f8c36c1 | ||
|
8e604a9da9 | ||
|
3e0233a26c | ||
|
aa98e2b37e | ||
|
7b53c0040c | ||
|
e6605637f8 | ||
|
6dfe0896e3 | ||
|
9f295cbb48 | ||
|
76c19e6111 | ||
|
6e6a2a013a | ||
|
2482e00224 | ||
|
7981b647c3 | ||
|
875bab352c | ||
|
862dc0001f | ||
|
adc3ec3851 | ||
|
5a6cd1cf3e | ||
|
5e2f514140 | ||
|
309e6dd82e | ||
|
6c5d296722 | ||
|
b1a1ab99aa | ||
|
1b69c14f45 | ||
|
cd8dea78e6 | ||
|
d77b35f333 | ||
|
6f7b927641 | ||
|
d2e20cf56c | ||
|
a6126b1370 | ||
|
87f0accb23 | ||
|
7add76dae8 | ||
|
2a2f10fddd | ||
|
0dd3285d56 | ||
|
f9782387d9 | ||
|
e1567707b1 | ||
|
08df55159b | ||
|
c29cc62d66 | ||
|
6ed07733cb | ||
|
ee3d3bd1e1 | ||
|
758954a93f | ||
|
590757e2b2 | ||
|
ddd6d54426 | ||
|
1a7cd887e4 | ||
|
d3c76575f9 | ||
|
b224270cc0 | ||
|
8b5b780c2c | ||
|
39c10f739d | ||
|
4fdc84f29e | ||
|
a8efe20862 | ||
|
58c5711b47 | ||
|
5d564a2f01 | ||
|
09c1476063 | ||
|
f255439ece | ||
|
b104e9ae78 | ||
|
4f964ce6ad | ||
|
11ec515378 | ||
|
1a9b1dd123 | ||
|
a93dfc1837 | ||
|
c5846378ab | ||
|
aea7d0c9c8 | ||
|
65c3f2dc85 |
48
.travis.yml
Normal file
48
.travis.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright 2016 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
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
install:
|
||||
- git clone -b $TRAVIS_BRANCH https://github.com/boostorg/boost.git boost
|
||||
- cd boost
|
||||
- git submodule init libs/align
|
||||
- git submodule init libs/assert
|
||||
- git submodule init libs/atomic
|
||||
- git submodule init libs/config
|
||||
- git submodule init libs/core
|
||||
- git submodule init libs/detail
|
||||
- git submodule init libs/functional
|
||||
- git submodule init libs/integer
|
||||
- git submodule init libs/move
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/preprocessor
|
||||
- git submodule init libs/smart_ptr
|
||||
- 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/inspect
|
||||
- git submodule update
|
||||
- cd libs/smart_ptr
|
||||
- git checkout -q $TRAVIS_COMMIT
|
||||
- cd ../..
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- TOOLSET=gcc,clang
|
||||
- if [ $TRAVIS_OS_NAME == osx ]; then TOOLSET=clang; fi
|
||||
- ./b2 libs/smart_ptr/test toolset=$TOOLSET
|
6
README.md
Normal file
6
README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Boost.SmartPtr
|
||||
|
||||
Branch | Travis | Appveyor
|
||||
---------|--------|---------
|
||||
Develop | [](https://travis-ci.org/boostorg/smart_ptr) | [](https://ci.appveyor.com/project/pdimov/smart_ptr)
|
||||
Master | [](https://travis-ci.org/boostorg/smart_ptr) | [](https://ci.appveyor.com/project/pdimov/smart_ptr)
|
44
appveyor.yml
Normal file
44
appveyor.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
# Copyright 2016 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)
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
install:
|
||||
- git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost
|
||||
- cd boost
|
||||
- git submodule init libs/align
|
||||
- git submodule init libs/assert
|
||||
- git submodule init libs/atomic
|
||||
- git submodule init libs/config
|
||||
- git submodule init libs/core
|
||||
- git submodule init libs/detail
|
||||
- git submodule init libs/functional
|
||||
- git submodule init libs/integer
|
||||
- git submodule init libs/move
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/preprocessor
|
||||
- git submodule init libs/smart_ptr
|
||||
- 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/inspect
|
||||
- git submodule update
|
||||
- cd libs\smart_ptr
|
||||
- git checkout -q %APPVEYOR_REPO_COMMIT%
|
||||
- cd ..\..
|
||||
- bootstrap
|
||||
- b2 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- b2 libs/smart_ptr/test toolset=msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
|
88
compatibility.htm
Normal file
88
compatibility.htm
Normal file
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Smart Pointer Changes</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||
width="277" align="middle" border="0">Smart Pointer Changes</h1>
|
||||
<p>The February 2002 change to the Boost smart pointers introduced a number of
|
||||
changes. Since the previous version of the smart pointers was in use for a long
|
||||
time, it's useful to have a detailed list of what changed from a library user's
|
||||
point of view.</p>
|
||||
<p>Note that for compilers that don't support member templates well enough, a
|
||||
separate implementation is used that lacks many of the new features and is more
|
||||
like the old version.</p>
|
||||
<h2>Features Requiring Code Changes to Take Advantage</h2>
|
||||
<ul>
|
||||
<li>
|
||||
The smart pointer class templates now each have their own header file. For
|
||||
compatibility, the <a href="../../boost/smart_ptr.hpp"><boost/smart_ptr.hpp></a>
|
||||
header now includes the headers for the four classic smart pointer class
|
||||
templates.
|
||||
<li>
|
||||
The <b>weak_ptr</b>
|
||||
template was added.
|
||||
<li>
|
||||
The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that
|
||||
the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
|
||||
destructor. This makes it easier to have shared_ptr members in classes without
|
||||
explicit destructors.
|
||||
<li>
|
||||
A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
|
||||
<li>
|
||||
<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
|
||||
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
|
||||
and <b>dynamic_cast</b>
|
||||
do for pointers.
|
||||
<li>
|
||||
The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
|
||||
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
|
||||
Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
|
||||
results in undefined behavior (an assertion, or eventually a double-delete if
|
||||
assertions are off).
|
||||
<li>
|
||||
The <b>BOOST_SMART_PTR_CONVERSION</b>
|
||||
feature has been removed.
|
||||
<li>
|
||||
<b>shared_ptr<void></b> is now allowed.</li>
|
||||
</ul>
|
||||
<h2>Features That Improve Robustness</h2>
|
||||
<ul>
|
||||
<li>
|
||||
The manipulation of use counts is now <a name="threadsafe">thread safe</a> on
|
||||
Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp">
|
||||
<boost/detail/atomic_count.hpp></a>
|
||||
file for details
|
||||
<li>
|
||||
The new shared_ptr will always delete the object using the pointer it was
|
||||
originally constructed with. This prevents subtle problems that could happen if
|
||||
the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did
|
||||
not have a virtual destructor.</li>
|
||||
</ul>
|
||||
<h2>Implementation Details</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Some bugs in the assignment operator implementations and in <b>reset</b>
|
||||
have been fixed by using the "copy and swap" idiom.
|
||||
<li>
|
||||
Assertions have been added to check preconditions of various functions;
|
||||
however, since these use the new <a href="../../boost/assert.hpp"><boost/assert.hpp></a>
|
||||
header, the assertions are disabled by default.
|
||||
<li>
|
||||
The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
|
||||
overloads which accomplish the same thing without relying on undefined
|
||||
behavior.
|
||||
<li>
|
||||
The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>,
|
||||
which has many of the same advantages for generic programming but does not
|
||||
violate the C++ standard.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<p>$Date$</p>
|
||||
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
110
enable_shared_from_this.html
Normal file
110
enable_shared_from_this.html
Normal file
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>enable_shared_from_this</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||
width="277" align="middle" border="0" />enable_shared_from_this</h1>
|
||||
<h2><a name="Purpose">Purpose</a></h2>
|
||||
<p>
|
||||
The header <code><boost/enable_shared_from_this.hpp></code> defines
|
||||
the class template <code>enable_shared_from_this</code>. It is used as a
|
||||
base class that allows a <a href="shared_ptr.htm">shared_ptr</a> or
|
||||
a <a href="weak_ptr.htm">weak_ptr</a> to the current object to be obtained
|
||||
from within a member function.
|
||||
</p>
|
||||
<p><code>enable_shared_from_this<T></code> defines two member functions
|
||||
called <code>shared_from_this</code> that return a <code>shared_ptr<T></code>
|
||||
and <code>shared_ptr<T const></code>, depending on constness, to <code>this</code>.
|
||||
It also defines two member functions called <code>weak_from_this</code> that return
|
||||
a corresponding <code>weak_ptr</code>.
|
||||
</p>
|
||||
<h2><a name="Example">Example</a></h2>
|
||||
<pre>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <cassert>
|
||||
|
||||
class Y: public boost::enable_shared_from_this<Y>
|
||||
{
|
||||
public:
|
||||
|
||||
boost::shared_ptr<Y> f()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<Y> p(new Y);
|
||||
boost::shared_ptr<Y> q = p->f();
|
||||
assert(p == q);
|
||||
assert(!(p < q || q < p)); // p and q must share ownership
|
||||
}
|
||||
</pre>
|
||||
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||
<pre>
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class enable_shared_from_this
|
||||
{
|
||||
public:
|
||||
|
||||
shared_ptr<T> shared_from_this();
|
||||
shared_ptr<T const> shared_from_this() const;
|
||||
|
||||
weak_ptr<T> weak_from_this() noexcept;
|
||||
weak_ptr<T const> weak_from_this() const noexcept;
|
||||
}
|
||||
|
||||
}
|
||||
</pre>
|
||||
<h4><code>template<class T> shared_ptr<T>
|
||||
enable_shared_from_this<T>::shared_from_this();</code></h4>
|
||||
<h4><code>template<class T> shared_ptr<T const>
|
||||
enable_shared_from_this<T>::shared_from_this() const;</code></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Requires:</b> <code>enable_shared_from_this<T></code> must be an
|
||||
accessible base class of <code>T</code>. <code>*this</code> must be a subobject
|
||||
of an instance <code>t</code> of type <code>T</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Returns:</b> If a <code>shared_ptr</code> instance <code>p</code> that <em>owns</em>
|
||||
<code>t</code> exists, a <code>shared_ptr<T></code> instance <code>r</code> that shares
|
||||
ownership with <code>p</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Postconditions:</b> <code>r.get() == this</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Throws:</b> <code>bad_weak_ptr</code> when no <code>shared_ptr</code> <em>owns</em> <code>*this</code>.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><code>template<class T> weak_ptr<T>
|
||||
enable_shared_from_this<T>::weak_from_this() noexcept;</code></h4>
|
||||
<h4><code>template<class T> weak_ptr<T const>
|
||||
enable_shared_from_this<T>::weak_from_this() const noexcept;</code></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Requires:</b> <code>enable_shared_from_this<T></code> must be an
|
||||
accessible base class of <code>T</code>. <code>*this</code> must be a subobject
|
||||
of an instance <code>t</code> of type <code>T</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Returns:</b> If a <code>shared_ptr</code> instance <code>p</code> that <em>owns</em>
|
||||
<code>t</code> exists or has existed in the past, a <code>weak_ptr<T></code> instance
|
||||
<code>r</code> that shares ownership with <code>p</code>. Otherwise, an empty <code>weak_ptr</code>.
|
||||
</p>
|
||||
</blockquote>
|
||||
<hr />
|
||||
<p>
|
||||
<small>Copyright © 2002, 2003, 2015 by Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
|
||||
copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
|
||||
</body>
|
||||
</html>
|
@@ -1,5 +1,12 @@
|
||||
// Boost scoped_ptr_example implementation file -----------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2001. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
// See http://www.boost.org/libs/smart_ptr for documentation.
|
||||
|
||||
#include "scoped_ptr_example.hpp"
|
||||
#include <iostream>
|
||||
|
@@ -1,6 +1,14 @@
|
||||
// Boost scoped_ptr_example header file ------------------------------------//
|
||||
|
||||
#include <boost/smart_ptr.hpp>
|
||||
// Copyright Beman Dawes 2001. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
// See http://www.boost.org/libs/smart_ptr for documentation.
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
// The point of this example is to prove that even though
|
||||
// example::implementation is an incomplete type in translation units using
|
||||
@@ -8,7 +16,7 @@
|
||||
// is complete where it counts - in the inplementation translation unit where
|
||||
// destruction is actually instantiated.
|
||||
|
||||
class example : boost::noncopyable
|
||||
class example : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
example();
|
17
example/scoped_ptr_example_test.cpp
Normal file
17
example/scoped_ptr_example_test.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// Boost scoped_ptr_example_test main program -------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2001. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
// See http://www.boost.org/libs/smart_ptr for documentation.
|
||||
|
||||
#include "scoped_ptr_example.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
example my_example;
|
||||
my_example.do_something();
|
||||
return 0;
|
||||
}
|
@@ -1,12 +1,11 @@
|
||||
// Boost shared_ptr_example.cpp --------------------------------------------//
|
||||
|
||||
// (C) Copyright Beman Dawes 2001. Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided "as is"
|
||||
// without express or implied warranty, and with no claim as to its
|
||||
// suitability for any purpose.
|
||||
// Copyright Beman Dawes 2001. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// See http://www.boost.org/libs/smart_ptr for documentation.
|
||||
|
||||
// Revision History
|
||||
// 21 May 01 Initial complete version (Beman Dawes)
|
||||
@@ -20,7 +19,7 @@
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <boost/smart_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// The application will produce a series of
|
||||
// objects of type Foo which later must be
|
@@ -1,5 +1,12 @@
|
||||
// Boost shared_ptr_example2 implementation file -----------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2001. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
// See http://www.boost.org/libs/smart_ptr for documentation.
|
||||
|
||||
#include "shared_ptr_example2.hpp"
|
||||
#include <iostream>
|
||||
|
||||
@@ -10,12 +17,6 @@ class example::implementation
|
||||
};
|
||||
|
||||
example::example() : _imp( new implementation ) {}
|
||||
example::example( const example & s ) : _imp( s._imp ) {}
|
||||
|
||||
example & example::operator=( const example & s )
|
||||
{ _imp = s._imp; return *this; }
|
||||
|
||||
void example::do_something()
|
||||
{ std::cout << "use_count() is " << _imp.use_count() << "\n"; }
|
||||
|
||||
example::~example() {}
|
@@ -1,6 +1,13 @@
|
||||
// Boost shared_ptr_example2 header file -----------------------------------//
|
||||
|
||||
#include <boost/smart_ptr.hpp>
|
||||
// Copyright Beman Dawes 2001. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
// See http://www.boost.org/libs/smart_ptr for documentation.
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// This example demonstrates the handle/body idiom (also called pimpl and
|
||||
// several other names). It separates the interface (in this header file)
|
||||
@@ -14,13 +21,10 @@
|
||||
|
||||
class example
|
||||
{
|
||||
public:
|
||||
public:
|
||||
example();
|
||||
~example();
|
||||
example( const example & );
|
||||
example & operator=( const example & );
|
||||
void do_something();
|
||||
private:
|
||||
private:
|
||||
class implementation;
|
||||
boost::shared_ptr< implementation > _imp; // hide implementation details
|
||||
};
|
22
example/shared_ptr_example2_test.cpp
Normal file
22
example/shared_ptr_example2_test.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
// Boost shared_ptr_example2_test main program ------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2001. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
// See http://www.boost.org/libs/smart_ptr for documentation.
|
||||
|
||||
#include "shared_ptr_example2.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
example a;
|
||||
a.do_something();
|
||||
example b(a);
|
||||
b.do_something();
|
||||
example c;
|
||||
c = a;
|
||||
c.do_something();
|
||||
return 0;
|
||||
}
|
21
include/boost/detail/atomic_count.hpp
Normal file
21
include/boost/detail/atomic_count.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count.hpp - thread/SMP safe reference counter
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// 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/smart_ptr/detail/atomic_count.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
22
include/boost/detail/lightweight_mutex.hpp
Normal file
22
include/boost/detail/lightweight_mutex.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lightweight_mutex.hpp - lightweight mutex
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// 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/smart_ptr/detail/lightweight_mutex.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
135
include/boost/detail/lightweight_thread.hpp
Normal file
135
include/boost/detail/lightweight_thread.hpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/detail/lightweight_thread.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2008 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>
|
||||
#include <memory>
|
||||
#include <cerrno>
|
||||
|
||||
// pthread_create, pthread_join
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
typedef HANDLE pthread_t;
|
||||
|
||||
int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
|
||||
{
|
||||
HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
|
||||
|
||||
if( h != 0 )
|
||||
{
|
||||
*thread = h;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_join( pthread_t thread, void ** /*value_ptr*/ )
|
||||
{
|
||||
::WaitForSingleObject( thread, INFINITE );
|
||||
::CloseHandle( thread );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// template<class F> int lw_thread_create( pthread_t & pt, F f );
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lw_abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~lw_abstract_thread() {}
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
extern "C" void * lw_thread_routine( void * pv )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
|
||||
|
||||
pt->run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
unsigned __stdcall lw_thread_routine( void * pv )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
|
||||
|
||||
pt->run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class F> class lw_thread_impl: public lw_abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
explicit lw_thread_impl( F f ): f_( f )
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
f_();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
F f_;
|
||||
};
|
||||
|
||||
template<class F> int lw_thread_create( pthread_t & pt, F f )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
|
||||
|
||||
int r = pthread_create( &pt, 0, lw_thread_routine, p.get() );
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
p.release();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
23
include/boost/detail/quick_allocator.hpp
Normal file
23
include/boost/detail/quick_allocator.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/quick_allocator.hpp
|
||||
//
|
||||
// Copyright (c) 2003 David Abrahams
|
||||
// Copyright (c) 2003 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/smart_ptr/detail/quick_allocator.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
18
include/boost/enable_shared_from_this.hpp
Normal file
18
include/boost/enable_shared_from_this.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// enable_shared_from_this.hpp
|
||||
//
|
||||
// Copyright (c) 2002 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
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_this.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
18
include/boost/intrusive_ptr.hpp
Normal file
18
include/boost/intrusive_ptr.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
#define BOOST_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// intrusive_ptr.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002 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
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
|
17
include/boost/make_shared.hpp
Normal file
17
include/boost/make_shared.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
|
||||
#define BOOST_MAKE_SHARED_HPP_INCLUDED
|
||||
|
||||
// make_shared.hpp
|
||||
//
|
||||
// Copyright (c) 2007, 2008 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
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
||||
// for documentation.
|
||||
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
|
14
include/boost/make_unique.hpp
Normal file
14
include/boost/make_unique.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
(c) 2014 Glen Joseph Fernandes
|
||||
<glenjofe -at- gmail.com>
|
||||
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0.
|
||||
http://boost.org/LICENSE_1_0.txt
|
||||
*/
|
||||
#ifndef BOOST_MAKE_UNIQUE_HPP_INCLUDED
|
||||
#define BOOST_MAKE_UNIQUE_HPP_INCLUDED
|
||||
|
||||
#include <boost/smart_ptr/make_unique.hpp>
|
||||
|
||||
#endif
|
45
include/boost/pointer_cast.hpp
Normal file
45
include/boost/pointer_cast.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_POINTER_CAST_HPP
|
||||
#define BOOST_POINTER_CAST_HPP
|
||||
|
||||
namespace boost {
|
||||
|
||||
//static_pointer_cast overload for raw pointers
|
||||
template<class T, class U>
|
||||
inline T* static_pointer_cast(U *ptr)
|
||||
{
|
||||
return static_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
//dynamic_pointer_cast overload for raw pointers
|
||||
template<class T, class U>
|
||||
inline T* dynamic_pointer_cast(U *ptr)
|
||||
{
|
||||
return dynamic_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
//const_pointer_cast overload for raw pointers
|
||||
template<class T, class U>
|
||||
inline T* const_pointer_cast(U *ptr)
|
||||
{
|
||||
return const_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
//reinterpret_pointer_cast overload for raw pointers
|
||||
template<class T, class U>
|
||||
inline T* reinterpret_pointer_cast(U *ptr)
|
||||
{
|
||||
return reinterpret_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif //BOOST_POINTER_CAST_HPP
|
55
include/boost/pointer_to_other.hpp
Normal file
55
include/boost/pointer_to_other.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
|
||||
#define BOOST_POINTER_TO_OTHER_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// pointer_to_other.hpp
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005.
|
||||
// Copyright (c) 2005 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/pointer_to_other.html
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Defines the same pointer type (raw or smart) to another pointee type
|
||||
|
||||
template<class T, class U>
|
||||
struct pointer_to_other;
|
||||
|
||||
template<class T, class U,
|
||||
template<class> class Sp>
|
||||
struct pointer_to_other< Sp<T>, U >
|
||||
{
|
||||
typedef Sp<U> type;
|
||||
};
|
||||
|
||||
template<class T, class T2, class U,
|
||||
template<class, class> class Sp>
|
||||
struct pointer_to_other< Sp<T, T2>, U >
|
||||
{
|
||||
typedef Sp<U, T2> type;
|
||||
};
|
||||
|
||||
template<class T, class T2, class T3, class U,
|
||||
template<class, class, class> class Sp>
|
||||
struct pointer_to_other< Sp<T, T2, T3>, U >
|
||||
{
|
||||
typedef Sp<U, T2, T3> type;
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
struct pointer_to_other< T*, U >
|
||||
{
|
||||
typedef U* type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
|
16
include/boost/scoped_array.hpp
Normal file
16
include/boost/scoped_array.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
||||
#define BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
||||
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 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)
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/scoped_array.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
16
include/boost/scoped_ptr.hpp
Normal file
16
include/boost/scoped_ptr.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
|
||||
#define BOOST_SCOPED_PTR_HPP_INCLUDED
|
||||
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 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)
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/scoped_ptr.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
|
19
include/boost/shared_array.hpp
Normal file
19
include/boost/shared_array.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
|
||||
#define BOOST_SHARED_ARRAY_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// shared_array.hpp
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/shared_array.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
|
19
include/boost/shared_ptr.hpp
Normal file
19
include/boost/shared_ptr.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
|
||||
#define BOOST_SHARED_PTR_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// shared_ptr.hpp
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001-2008 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
|
@@ -1,402 +1,31 @@
|
||||
// Boost smart_ptr.hpp header file -----------------------------------------//
|
||||
#ifndef BOOST_SMART_PTR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_HPP_INCLUDED
|
||||
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided "as is"
|
||||
// without express or implied warranty, and with no claim as to its
|
||||
// suitability for any purpose.
|
||||
//
|
||||
// smart_ptr.hpp
|
||||
//
|
||||
// For convenience, this header includes the rest of the smart
|
||||
// pointer library headers.
|
||||
//
|
||||
// Copyright (c) 2003 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)
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
//
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Revision History
|
||||
// 6 Jul 01 Reorder shared_ptr code so VC++ 6 member templates work, allowing
|
||||
// polymorphic pointers to now work with that compiler (Gary Powell)
|
||||
// 21 May 01 Require complete type where incomplete type is unsafe.
|
||||
// (suggested by Vladimir Prus)
|
||||
// 21 May 01 operator= fails if operand transitively owned by *this, as in a
|
||||
// linked list (report by Ken Johnson, fix by Beman Dawes)
|
||||
// 21 Jan 01 Suppress some useless warnings with MSVC (David Abrahams)
|
||||
// 19 Oct 00 Make shared_ptr ctor from auto_ptr explicit. (Robert Vugts)
|
||||
// 24 Jul 00 Change throw() to // never throws. See lib guidelines
|
||||
// Exception-specification rationale. (Beman Dawes)
|
||||
// 22 Jun 00 Remove #if continuations to fix GCC 2.95.2 problem (Beman Dawes)
|
||||
// 1 Feb 00 Additional shared_ptr BOOST_NO_MEMBER_TEMPLATES workarounds
|
||||
// (Dave Abrahams)
|
||||
// 31 Dec 99 Condition tightened for no member template friend workaround
|
||||
// (Dave Abrahams)
|
||||
// 30 Dec 99 Moved BOOST_NMEMBER_TEMPLATES compatibility code to config.hpp
|
||||
// (Dave Abrahams)
|
||||
// 30 Nov 99 added operator ==, operator !=, and std::swap and std::less
|
||||
// specializations for shared types (Darin Adler)
|
||||
// 11 Oct 99 replaced op[](int) with op[](std::size_t) (Ed Brey, Valentin
|
||||
// Bonnard), added shared_ptr workaround for no member template
|
||||
// friends (Matthew Langston)
|
||||
// 25 Sep 99 added shared_ptr::swap and shared_array::swap (Luis Coelho).
|
||||
// 20 Jul 99 changed name to smart_ptr.hpp, #include <boost/config.hpp>,
|
||||
// #include <boost/utility.hpp> and use boost::noncopyable
|
||||
// 17 May 99 remove scoped_array and shared_array operator*() as
|
||||
// unnecessary (Beman Dawes)
|
||||
// 14 May 99 reorder code so no effects when bad_alloc thrown (Abrahams/Dawes)
|
||||
// 13 May 99 remove certain throw() specifiers to avoid generated try/catch
|
||||
// code cost (Beman Dawes)
|
||||
// 11 May 99 get() added, conversion to T* placed in macro guard (Valentin
|
||||
// Bonnard, Dave Abrahams, and others argued for elimination
|
||||
// of the automatic conversion)
|
||||
// 28 Apr 99 #include <memory> fix (Valentin Bonnard)
|
||||
// 28 Apr 99 rename transfer() to share() for clarity (Dave Abrahams)
|
||||
// 28 Apr 99 remove unsafe shared_array template conversions(Valentin Bonnard)
|
||||
// 28 Apr 99 p(r) changed to p(r.px) for clarity (Dave Abrahams)
|
||||
// 21 Apr 99 reset() self assignment fix (Valentin Bonnard)
|
||||
// 21 Apr 99 dispose() provided to improve clarity (Valentin Bonnard)
|
||||
// 27 Apr 99 leak when new throws fixes (Dave Abrahams)
|
||||
// 21 Oct 98 initial Version (Greg Colvin/Beman Dawes)
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
|
||||
#ifndef BOOST_SMART_PTR_HPP
|
||||
#define BOOST_SMART_PTR_HPP
|
||||
|
||||
#include <boost/config.hpp> // for broken compiler workarounds
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <memory> // for std::auto_ptr
|
||||
#include <algorithm> // for std::swap
|
||||
#include <boost/utility.hpp> // for boost::noncopyable, checked_delete, checked_array_delete
|
||||
#include <functional> // for std::less
|
||||
#include <boost/static_assert.hpp> // for BOOST_STATIC_ASSERT
|
||||
|
||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4284) // return type for 'identifier::operator->' is not a UDT or reference to a UDT. Will produce errors if applied using infix notation
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
// scoped_ptr --------------------------------------------------------------//
|
||||
|
||||
// scoped_ptr mimics a built-in pointer except that it guarantees deletion
|
||||
// of the object pointed to, either on destruction of the scoped_ptr or via
|
||||
// an explicit reset(). scoped_ptr is a simple solution for simple needs;
|
||||
// see shared_ptr (below) or std::auto_ptr if your needs are more complex.
|
||||
|
||||
template<typename T> class scoped_ptr : noncopyable {
|
||||
|
||||
T* ptr;
|
||||
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_ptr( T* p=0 ) : ptr(p) {} // never throws
|
||||
~scoped_ptr() { checked_delete(ptr); }
|
||||
void reset( T* p=0 ) { if ( ptr != p ) { checked_delete(ptr); ptr = p; } }
|
||||
T& operator*() const { return *ptr; } // never throws
|
||||
T* operator->() const { return ptr; } // never throws
|
||||
T* get() const { return ptr; } // never throws
|
||||
#ifdef BOOST_SMART_PTR_CONVERSION
|
||||
// get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
|
||||
operator T*() const { return ptr; } // never throws
|
||||
#endif
|
||||
}; // scoped_ptr
|
||||
|
||||
// scoped_array ------------------------------------------------------------//
|
||||
|
||||
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
|
||||
// is guaranteed, either on destruction of the scoped_array or via an explicit
|
||||
// reset(). See shared_array or std::vector if your needs are more complex.
|
||||
|
||||
template<typename T> class scoped_array : noncopyable {
|
||||
|
||||
T* ptr;
|
||||
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_array( T* p=0 ) : ptr(p) {} // never throws
|
||||
~scoped_array() { checked_array_delete(ptr); }
|
||||
|
||||
void reset( T* p=0 ) { if ( ptr != p )
|
||||
{checked_array_delete(ptr); ptr=p;} }
|
||||
|
||||
T* get() const { return ptr; } // never throws
|
||||
#ifdef BOOST_SMART_PTR_CONVERSION
|
||||
// get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
|
||||
operator T*() const { return ptr; } // never throws
|
||||
#else
|
||||
T& operator[](std::size_t i) const { return ptr[i]; } // never throws
|
||||
#endif
|
||||
}; // scoped_array
|
||||
|
||||
// shared_ptr --------------------------------------------------------------//
|
||||
|
||||
// An enhanced relative of scoped_ptr with reference counted copy semantics.
|
||||
// The object pointed to is deleted when the last shared_ptr pointing to it
|
||||
// is destroyed or reset.
|
||||
|
||||
template<typename T> class shared_ptr {
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
explicit shared_ptr(T* p =0) : px(p) {
|
||||
try { pn = new long(1); } // fix: prevent leak if new throws
|
||||
catch (...) { checked_delete(p); throw; }
|
||||
}
|
||||
|
||||
~shared_ptr() { dispose(); }
|
||||
|
||||
#if !defined( BOOST_NO_MEMBER_TEMPLATES ) || defined (BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
template<typename Y>
|
||||
shared_ptr(const shared_ptr<Y>& r) : px(r.px) { // never throws
|
||||
++*(pn = r.pn);
|
||||
}
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
template<typename Y>
|
||||
explicit shared_ptr(std::auto_ptr<Y>& r) {
|
||||
pn = new long(1); // may throw
|
||||
px = r.release(); // fix: moved here to stop leak if new throws
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr& operator=(const shared_ptr<Y>& r) {
|
||||
share(r.px,r.pn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
template<typename Y>
|
||||
shared_ptr& operator=(std::auto_ptr<Y>& r) {
|
||||
// code choice driven by guarantee of "no effect if new throws"
|
||||
if (*pn == 1) { checked_delete(px); }
|
||||
else { // allocate new reference counter
|
||||
long * tmp = new long(1); // may throw
|
||||
--*pn; // only decrement once danger of new throwing is past
|
||||
pn = tmp;
|
||||
} // allocate new reference counter
|
||||
px = r.release(); // fix: moved here so doesn't leak if new throws
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
explicit shared_ptr(std::auto_ptr<T>& r) {
|
||||
pn = new long(1); // may throw
|
||||
px = r.release(); // fix: moved here to stop leak if new throws
|
||||
}
|
||||
|
||||
shared_ptr& operator=(std::auto_ptr<T>& r) {
|
||||
// code choice driven by guarantee of "no effect if new throws"
|
||||
if (*pn == 1) { checked_delete(px); }
|
||||
else { // allocate new reference counter
|
||||
long * tmp = new long(1); // may throw
|
||||
--*pn; // only decrement once danger of new throwing is past
|
||||
pn = tmp;
|
||||
} // allocate new reference counter
|
||||
px = r.release(); // fix: moved here so doesn't leak if new throws
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
# include <boost/weak_ptr.hpp>
|
||||
# include <boost/intrusive_ptr.hpp>
|
||||
# include <boost/enable_shared_from_this.hpp>
|
||||
# include <boost/make_shared.hpp>
|
||||
#endif
|
||||
|
||||
// The assignment operator and the copy constructor must come after
|
||||
// the templated versions for MSVC6 to work. (Gary Powell)
|
||||
shared_ptr(const shared_ptr& r) : px(r.px) { ++*(pn = r.pn); } // never throws
|
||||
|
||||
shared_ptr& operator=(const shared_ptr& r) {
|
||||
share(r.px,r.pn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset(T* p=0) {
|
||||
if ( px == p ) return; // fix: self-assignment safe
|
||||
if (--*pn == 0) { checked_delete(px); }
|
||||
else { // allocate new reference counter
|
||||
try { pn = new long; } // fix: prevent leak if new throws
|
||||
catch (...) {
|
||||
++*pn; // undo effect of --*pn above to meet effects guarantee
|
||||
checked_delete(p);
|
||||
throw;
|
||||
} // catch
|
||||
} // allocate new reference counter
|
||||
*pn = 1;
|
||||
px = p;
|
||||
} // reset
|
||||
|
||||
T& operator*() const { return *px; } // never throws
|
||||
T* operator->() const { return px; } // never throws
|
||||
T* get() const { return px; } // never throws
|
||||
#ifdef BOOST_SMART_PTR_CONVERSION
|
||||
// get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
|
||||
operator T*() const { return px; } // never throws
|
||||
#endif
|
||||
|
||||
long use_count() const { return *pn; } // never throws
|
||||
bool unique() const { return *pn == 1; } // never throws
|
||||
|
||||
void swap(shared_ptr<T>& other) // never throws
|
||||
{ std::swap(px,other.px); std::swap(pn,other.pn); }
|
||||
|
||||
// Tasteless as this may seem, making all members public allows member templates
|
||||
// to work in the absence of member template friends. (Matthew Langston)
|
||||
// Don't split this line into two; that causes problems for some GCC 2.95.2 builds
|
||||
#if ( defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) ) || !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
|
||||
private:
|
||||
#endif
|
||||
|
||||
T* px; // contained pointer
|
||||
long* pn; // ptr to reference counter
|
||||
|
||||
// Don't split this line into two; that causes problems for some GCC 2.95.2 builds
|
||||
#if !defined( BOOST_NO_MEMBER_TEMPLATES ) && !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
|
||||
template<typename Y> friend class shared_ptr;
|
||||
#endif
|
||||
|
||||
void dispose() { if (--*pn == 0) { checked_delete(px); delete pn; } }
|
||||
|
||||
void share(T* rpx, long* rpn) {
|
||||
if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0
|
||||
++*rpn; // done before dispose() in case rpn transitively
|
||||
// dependent on *this (bug reported by Ken Johnson)
|
||||
dispose();
|
||||
px = rpx;
|
||||
pn = rpn;
|
||||
}
|
||||
} // share
|
||||
}; // shared_ptr
|
||||
|
||||
template<typename T, typename U>
|
||||
inline bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b)
|
||||
{ return a.get() == b.get(); }
|
||||
|
||||
template<typename T, typename U>
|
||||
inline bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b)
|
||||
{ return a.get() != b.get(); }
|
||||
|
||||
// shared_array ------------------------------------------------------------//
|
||||
|
||||
// shared_array extends shared_ptr to arrays.
|
||||
// The array pointed to is deleted when the last shared_array pointing to it
|
||||
// is destroyed or reset.
|
||||
|
||||
template<typename T> class shared_array {
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
explicit shared_array(T* p =0) : px(p) {
|
||||
try { pn = new long(1); } // fix: prevent leak if new throws
|
||||
catch (...) { checked_array_delete(p); throw; }
|
||||
}
|
||||
|
||||
shared_array(const shared_array& r) : px(r.px) // never throws
|
||||
{ ++*(pn = r.pn); }
|
||||
|
||||
~shared_array() { dispose(); }
|
||||
|
||||
shared_array& operator=(const shared_array& r) {
|
||||
if (pn != r.pn) { // Q: why not px != r.px? A: fails when both px == 0
|
||||
++*r.pn; // done before dispose() in case r.pn transitively
|
||||
// dependent on *this (bug reported by Ken Johnson)
|
||||
dispose();
|
||||
px = r.px;
|
||||
pn = r.pn;
|
||||
}
|
||||
return *this;
|
||||
} // operator=
|
||||
|
||||
void reset(T* p=0) {
|
||||
if ( px == p ) return; // fix: self-assignment safe
|
||||
if (--*pn == 0) { checked_array_delete(px); }
|
||||
else { // allocate new reference counter
|
||||
try { pn = new long; } // fix: prevent leak if new throws
|
||||
catch (...) {
|
||||
++*pn; // undo effect of --*pn above to meet effects guarantee
|
||||
checked_array_delete(p);
|
||||
throw;
|
||||
} // catch
|
||||
} // allocate new reference counter
|
||||
*pn = 1;
|
||||
px = p;
|
||||
} // reset
|
||||
|
||||
T* get() const { return px; } // never throws
|
||||
#ifdef BOOST_SMART_PTR_CONVERSION
|
||||
// get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
|
||||
operator T*() const { return px; } // never throws
|
||||
#else
|
||||
T& operator[](std::size_t i) const { return px[i]; } // never throws
|
||||
#endif
|
||||
|
||||
long use_count() const { return *pn; } // never throws
|
||||
bool unique() const { return *pn == 1; } // never throws
|
||||
|
||||
void swap(shared_array<T>& other) // never throws
|
||||
{ std::swap(px,other.px); std::swap(pn,other.pn); }
|
||||
|
||||
private:
|
||||
|
||||
T* px; // contained pointer
|
||||
long* pn; // ptr to reference counter
|
||||
|
||||
void dispose() { if (--*pn == 0) { checked_array_delete(px); delete pn; } }
|
||||
|
||||
}; // shared_array
|
||||
|
||||
template<typename T>
|
||||
inline bool operator==(const shared_array<T>& a, const shared_array<T>& b)
|
||||
{ return a.get() == b.get(); }
|
||||
|
||||
template<typename T>
|
||||
inline bool operator!=(const shared_array<T>& a, const shared_array<T>& b)
|
||||
{ return a.get() != b.get(); }
|
||||
|
||||
} // namespace boost
|
||||
|
||||
// specializations for things in namespace std -----------------------------//
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
namespace std {
|
||||
|
||||
// Specialize std::swap to use the fast, non-throwing swap that's provided
|
||||
// as a member function instead of using the default algorithm which creates
|
||||
// a temporary and uses assignment.
|
||||
|
||||
template<typename T>
|
||||
inline void swap(boost::shared_ptr<T>& a, boost::shared_ptr<T>& b)
|
||||
{ a.swap(b); }
|
||||
|
||||
template<typename T>
|
||||
inline void swap(boost::shared_array<T>& a, boost::shared_array<T>& b)
|
||||
{ a.swap(b); }
|
||||
|
||||
// Specialize std::less so we can use shared pointers and arrays as keys in
|
||||
// associative collections.
|
||||
|
||||
// It's still a controversial question whether this is better than supplying
|
||||
// a full range of comparison operators (<, >, <=, >=).
|
||||
|
||||
template<typename T>
|
||||
struct less< boost::shared_ptr<T> >
|
||||
: binary_function<boost::shared_ptr<T>, boost::shared_ptr<T>, bool>
|
||||
{
|
||||
bool operator()(const boost::shared_ptr<T>& a,
|
||||
const boost::shared_ptr<T>& b) const
|
||||
{ return less<T*>()(a.get(),b.get()); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct less< boost::shared_array<T> >
|
||||
: binary_function<boost::shared_array<T>, boost::shared_array<T>, bool>
|
||||
{
|
||||
bool operator()(const boost::shared_array<T>& a,
|
||||
const boost::shared_array<T>& b) const
|
||||
{ return less<T*>()(a.get(),b.get()); }
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_SMART_PTR_HPP
|
||||
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED
|
||||
|
181
include/boost/smart_ptr/allocate_shared_array.hpp
Normal file
181
include/boost/smart_ptr/allocate_shared_array.hpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_count_impl.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared(const A& allocator, std::size_t size) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_init_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(allocator, size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
boost::detail::as_init(allocator, p2, n1);
|
||||
#else
|
||||
boost::detail::ms_init(p2, n1);
|
||||
#endif
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared(const A& allocator) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_init_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(allocator, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
boost::detail::as_init(allocator, p2, N);
|
||||
#else
|
||||
boost::detail::ms_init(p2, N);
|
||||
#endif
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared(const A& allocator, std::size_t size,
|
||||
const typename boost::detail::array_inner<T>::type& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
typedef boost::detail::ms_init_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size
|
||||
};
|
||||
std::size_t n1 = M * size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = reinterpret_cast<T3*>(&value);
|
||||
D1 d1;
|
||||
A1 a1(allocator, size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
boost::detail::as_init<T2, A, M>(allocator, p2, n1, p3);
|
||||
#else
|
||||
boost::detail::ms_init<T2, M>(p2, n1, p3);
|
||||
#endif
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared(const A& allocator,
|
||||
const typename boost::detail::array_inner<T>::type& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
typedef boost::detail::ms_init_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size,
|
||||
M = boost::detail::array_total<T1>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = reinterpret_cast<T3*>(&value);
|
||||
D1 d1;
|
||||
A1 a1(allocator, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
boost::detail::as_init<T2, A, M>(allocator, p2, N, p3);
|
||||
#else
|
||||
boost::detail::ms_init<T2, M>(p2, N, p3);
|
||||
#endif
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared_noinit(const A& allocator, std::size_t size) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_noinit_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(allocator, size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_noinit(p2, n1);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared_noinit(const A& allocator) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_noinit_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(allocator, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_noinit(p2, N);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
59
include/boost/smart_ptr/bad_weak_ptr.hpp
Normal file
59
include/boost/smart_ptr/bad_weak_ptr.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/smart_ptr/bad_weak_ptr.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// 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 <exception>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// The standard library that comes with Borland C++ 5.5.1, 5.6.4
|
||||
// defines std::exception and its members as having C calling
|
||||
// convention (-pc). When the definition of bad_weak_ptr
|
||||
// is compiled with -ps, the compiler issues an error.
|
||||
// Hence, the temporary #pragma option -pc below.
|
||||
|
||||
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
|
||||
# pragma option push -pc
|
||||
#endif
|
||||
|
||||
class bad_weak_ptr: public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
virtual char const * what() const throw()
|
||||
{
|
||||
return "tr1::bad_weak_ptr";
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
|
||||
# pragma option pop
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
|
318
include/boost/smart_ptr/detail/array_allocator.hpp
Normal file
318
include/boost/smart_ptr/detail/array_allocator.hpp
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
|
||||
|
||||
#include <boost/align/align.hpp>
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/smart_ptr/detail/array_utility.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
struct ms_init_tag { };
|
||||
struct ms_noinit_tag { };
|
||||
|
||||
template<class T>
|
||||
struct ms_allocator_state;
|
||||
|
||||
template<class T>
|
||||
struct ms_allocator_state<T[]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
|
||||
ms_allocator_state(std::size_t size_,
|
||||
type** result_)
|
||||
: size(size_ * array_total<T>::size),
|
||||
result(result_) {
|
||||
}
|
||||
|
||||
std::size_t size;
|
||||
|
||||
union {
|
||||
type** result;
|
||||
type* object;
|
||||
};
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct ms_allocator_state<T[N]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
|
||||
ms_allocator_state(type** result_)
|
||||
: result(result_) {
|
||||
}
|
||||
|
||||
enum {
|
||||
size = array_total<T[N]>::size
|
||||
};
|
||||
|
||||
union {
|
||||
type** result;
|
||||
type* object;
|
||||
};
|
||||
};
|
||||
|
||||
template<class A, class T, class R>
|
||||
class as_allocator
|
||||
: public A {
|
||||
template<class A_, class T_, class R_>
|
||||
friend class as_allocator;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef std::allocator_traits<A> AT;
|
||||
typedef typename AT::template rebind_alloc<char> CA;
|
||||
typedef typename AT::template rebind_traits<char> CT;
|
||||
#else
|
||||
typedef typename A::template rebind<char>::other CA;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef A allocator_type;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename AT::value_type value_type;
|
||||
typedef typename AT::pointer pointer;
|
||||
typedef typename AT::const_pointer const_pointer;
|
||||
typedef typename AT::void_pointer void_pointer;
|
||||
typedef typename AT::const_void_pointer const_void_pointer;
|
||||
typedef typename AT::size_type size_type;
|
||||
typedef typename AT::difference_type difference_type;
|
||||
#else
|
||||
typedef typename A::value_type value_type;
|
||||
typedef typename A::pointer pointer;
|
||||
typedef typename A::const_pointer const_pointer;
|
||||
typedef typename A::size_type size_type;
|
||||
typedef typename A::difference_type difference_type;
|
||||
typedef typename A::reference reference;
|
||||
typedef typename A::const_reference const_reference;
|
||||
typedef void* void_pointer;
|
||||
typedef const void* const_void_pointer;
|
||||
#endif
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef as_allocator<typename AT::
|
||||
template rebind_alloc<U>, T, R> other;
|
||||
#else
|
||||
typedef as_allocator<typename A::
|
||||
template rebind<U>::other, T, R> other;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef typename array_base<T>::type type;
|
||||
|
||||
as_allocator(const A& allocator_, type** result)
|
||||
: A(allocator_),
|
||||
data(result) {
|
||||
}
|
||||
|
||||
as_allocator(const A& allocator_, std::size_t size,
|
||||
type** result)
|
||||
: A(allocator_),
|
||||
data(size, result) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
as_allocator(const as_allocator<U, T, R>& other)
|
||||
: A(other.allocator()),
|
||||
data(other.data) {
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const_void_pointer = 0) {
|
||||
enum {
|
||||
M = boost::alignment_of<type>::value
|
||||
};
|
||||
std::size_t n1 = count * sizeof(value_type);
|
||||
std::size_t n2 = data.size * sizeof(type);
|
||||
std::size_t n3 = n2 + M;
|
||||
CA ca(allocator());
|
||||
void* p1 = ca.allocate(n1 + n3);
|
||||
void* p2 = static_cast<char*>(p1) + n1;
|
||||
(void)boost::alignment::align(M, n2, p2, n3);
|
||||
*data.result = static_cast<type*>(p2);
|
||||
return static_cast<value_type*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type count) {
|
||||
enum {
|
||||
M = boost::alignment_of<type>::value
|
||||
};
|
||||
std::size_t n1 = count * sizeof(value_type);
|
||||
std::size_t n2 = data.size * sizeof(type) + M;
|
||||
char* p1 = reinterpret_cast<char*>(memory);
|
||||
CA ca(allocator());
|
||||
ca.deallocate(p1, n1 + n2);
|
||||
}
|
||||
|
||||
const A& allocator() const {
|
||||
return static_cast<const A&>(*this);
|
||||
}
|
||||
|
||||
A& allocator() {
|
||||
return static_cast<A&>(*this);
|
||||
}
|
||||
|
||||
void set(type* memory) {
|
||||
data.object = memory;
|
||||
}
|
||||
|
||||
void operator()() {
|
||||
if (data.object) {
|
||||
R tag;
|
||||
release(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void release(ms_init_tag) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
as_destroy(allocator(), data.object, data.size);
|
||||
#else
|
||||
ms_destroy(data.object, data.size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void release(ms_noinit_tag) {
|
||||
ms_destroy(data.object, data.size);
|
||||
}
|
||||
|
||||
ms_allocator_state<T> data;
|
||||
};
|
||||
|
||||
template<class A1, class A2, class T, class R>
|
||||
bool operator==(const as_allocator<A1, T, R>& a1,
|
||||
const as_allocator<A2, T, R>& a2) {
|
||||
return a1.allocator() == a2.allocator();
|
||||
}
|
||||
|
||||
template<class A1, class A2, class T, class R>
|
||||
bool operator!=(const as_allocator<A1, T, R>& a1,
|
||||
const as_allocator<A2, T, R>& a2) {
|
||||
return a1.allocator() != a2.allocator();
|
||||
}
|
||||
|
||||
template<class T, class Y = char>
|
||||
class ms_allocator;
|
||||
|
||||
template<class T, class Y>
|
||||
class ms_allocator {
|
||||
template<class T_, class Y_>
|
||||
friend class ms_allocator;
|
||||
|
||||
public:
|
||||
typedef typename array_base<T>::type type;
|
||||
|
||||
typedef Y value_type;
|
||||
typedef Y* pointer;
|
||||
typedef const Y* const_pointer;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Y& reference;
|
||||
typedef const Y& const_reference;
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
typedef ms_allocator<T, U> other;
|
||||
};
|
||||
|
||||
ms_allocator(type** result)
|
||||
: data(result) {
|
||||
}
|
||||
|
||||
ms_allocator(std::size_t size, type** result)
|
||||
: data(size, result) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
ms_allocator(const ms_allocator<T, U>& other)
|
||||
: data(other.data) {
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const void* = 0) {
|
||||
enum {
|
||||
M = boost::alignment_of<type>::value
|
||||
};
|
||||
std::size_t n1 = count * sizeof(Y);
|
||||
std::size_t n2 = data.size * sizeof(type);
|
||||
std::size_t n3 = n2 + M;
|
||||
void* p1 = ::operator new(n1 + n3);
|
||||
void* p2 = static_cast<char*>(p1) + n1;
|
||||
(void)boost::alignment::align(M, n2, p2, n3);
|
||||
*data.result = static_cast<type*>(p2);
|
||||
return static_cast<Y*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type) {
|
||||
void* p1 = memory;
|
||||
::operator delete(p1);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
pointer address(reference value) const {
|
||||
return &value;
|
||||
}
|
||||
|
||||
const_pointer address(const_reference value) const {
|
||||
return &value;
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
enum {
|
||||
N = static_cast<std::size_t>(-1) / sizeof(Y)
|
||||
};
|
||||
return N;
|
||||
}
|
||||
|
||||
void construct(pointer memory, const_reference value) {
|
||||
void* p1 = memory;
|
||||
::new(p1) Y(value);
|
||||
}
|
||||
|
||||
void destroy(pointer memory) {
|
||||
(void)memory;
|
||||
memory->~Y();
|
||||
}
|
||||
#endif
|
||||
|
||||
void set(type* memory) {
|
||||
data.object = memory;
|
||||
}
|
||||
|
||||
void operator()() {
|
||||
if (data.object) {
|
||||
ms_destroy(data.object, data.size);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ms_allocator_state<T> data;
|
||||
};
|
||||
|
||||
template<class T, class Y1, class Y2>
|
||||
bool operator==(const ms_allocator<T, Y1>&,
|
||||
const ms_allocator<T, Y2>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T, class Y1, class Y2>
|
||||
bool operator!=(const ms_allocator<T, Y1>&,
|
||||
const ms_allocator<T, Y2>&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
class ms_in_allocator_tag {
|
||||
public:
|
||||
void operator()(const void*) {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
67
include/boost/smart_ptr/detail/array_count_impl.hpp
Normal file
67
include/boost/smart_ptr/detail/array_count_impl.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_allocator.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<class P, class A>
|
||||
class sp_counted_impl_pda<P, ms_in_allocator_tag, A>
|
||||
: public sp_counted_base {
|
||||
typedef ms_in_allocator_tag D;
|
||||
typedef sp_counted_impl_pda<P, D, A> Y;
|
||||
public:
|
||||
sp_counted_impl_pda(P, D, const A& allocator_)
|
||||
: allocator(allocator_) {
|
||||
}
|
||||
|
||||
virtual void dispose() {
|
||||
allocator();
|
||||
}
|
||||
|
||||
virtual void destroy() {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<Y> YA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<Y> YT;
|
||||
#else
|
||||
typedef typename A::template rebind<Y>::other YA;
|
||||
#endif
|
||||
YA a1(allocator);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
YT::destroy(a1, this);
|
||||
YT::deallocate(a1, this, 1);
|
||||
#else
|
||||
this->~Y();
|
||||
a1.deallocate(this, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void* get_deleter(const sp_typeinfo&) {
|
||||
return &reinterpret_cast<char&>(allocator);
|
||||
}
|
||||
|
||||
virtual void* get_untyped_deleter() {
|
||||
return &reinterpret_cast<char&>(allocator);
|
||||
}
|
||||
|
||||
private:
|
||||
sp_counted_impl_pda(const sp_counted_impl_pda&);
|
||||
sp_counted_impl_pda& operator=(const sp_counted_impl_pda&);
|
||||
|
||||
A allocator;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
60
include/boost/smart_ptr/detail/array_traits.hpp
Normal file
60
include/boost/smart_ptr/detail/array_traits.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
|
||||
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<class T>
|
||||
struct array_base {
|
||||
typedef typename boost::remove_cv<T>::type type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct array_base<T[]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct array_base<T[N]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct array_total {
|
||||
enum {
|
||||
size = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct array_total<T[N]> {
|
||||
enum {
|
||||
size = N * array_total<T>::size
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct array_inner;
|
||||
|
||||
template<class T>
|
||||
struct array_inner<T[]> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct array_inner<T[N]> {
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
214
include/boost/smart_ptr/detail/array_utility.hpp
Normal file
214
include/boost/smart_ptr/detail/array_utility.hpp
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
typedef boost::true_type ms_is_trivial;
|
||||
typedef boost::false_type ms_no_trivial;
|
||||
|
||||
template<class T>
|
||||
inline void ms_destroy(T*, std::size_t, ms_is_trivial) {
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) {
|
||||
for (std::size_t i = size; i > 0;) {
|
||||
memory[--i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_destroy(T* memory, std::size_t size) {
|
||||
boost::has_trivial_destructor<T> trivial;
|
||||
ms_destroy(memory, size, trivial);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_init(T* memory, std::size_t size, ms_is_trivial) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_init(T* memory, std::size_t size, ms_no_trivial) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
} catch (...) {
|
||||
ms_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_init(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
ms_init(memory, size, trivial);
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline void ms_init(T* memory, std::size_t size, const T* list) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(list[i % N]);
|
||||
}
|
||||
} catch (...) {
|
||||
ms_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(list[i % N]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class T, class A>
|
||||
inline void as_destroy(const A& allocator, T* memory,
|
||||
std::size_t size) {
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<T> TA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<T> TT;
|
||||
TA a2(allocator);
|
||||
for (std::size_t i = size; i > 0;) {
|
||||
TT::destroy(a2, &memory[--i]);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size,
|
||||
ms_is_trivial) {
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<T> TA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<T> TT;
|
||||
TA a2(allocator);
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
TT::construct(a2, memory + i);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size,
|
||||
ms_no_trivial) {
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<T> TA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<T> TT;
|
||||
TA a2(allocator);
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
TT::construct(a2, memory + i);
|
||||
}
|
||||
} catch (...) {
|
||||
as_destroy(a2, memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
TT::construct(a2, memory + i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
as_init(allocator, memory, size, trivial);
|
||||
}
|
||||
|
||||
template<class T, class A, std::size_t N>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size,
|
||||
const T* list) {
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<T> TA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<T> TT;
|
||||
TA a2(allocator);
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
TT::construct(a2, memory + i, list[i % N]);
|
||||
}
|
||||
} catch (...) {
|
||||
as_destroy(a2, memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
TT::construct(a2, memory + i, list[i % N]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline void ms_noinit(T*, std::size_t, ms_is_trivial) {
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T;
|
||||
}
|
||||
} catch (...) {
|
||||
ms_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_noinit(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
ms_noinit(memory, size, trivial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
96
include/boost/smart_ptr/detail/atomic_count.hpp
Normal file
96
include/boost/smart_ptr/detail/atomic_count.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count.hpp - thread/SMP safe reference counter
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2013 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
|
||||
//
|
||||
// typedef <implementation-defined> boost::detail::atomic_count;
|
||||
//
|
||||
// atomic_count a(n);
|
||||
//
|
||||
// (n is convertible to long)
|
||||
//
|
||||
// Effects: Constructs an atomic_count with an initial value of n
|
||||
//
|
||||
// a;
|
||||
//
|
||||
// Returns: (long) the current value of a
|
||||
// Memory Ordering: acquire
|
||||
//
|
||||
// ++a;
|
||||
//
|
||||
// Effects: Atomically increments the value of a
|
||||
// Returns: (long) the new value of a
|
||||
// Memory Ordering: acquire/release
|
||||
//
|
||||
// --a;
|
||||
//
|
||||
// Effects: Atomically decrements the value of a
|
||||
// Returns: (long) the new value of a
|
||||
// Memory Ordering: acquire/release
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
|
||||
|
||||
#if defined( BOOST_AC_DISABLE_THREADS )
|
||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
|
||||
|
||||
#elif defined( BOOST_AC_USE_STD_ATOMIC )
|
||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
|
||||
|
||||
#elif defined( BOOST_AC_USE_SPINLOCK )
|
||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
|
||||
|
||||
#elif defined( BOOST_AC_USE_PTHREADS )
|
||||
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_DISABLE_THREADS )
|
||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_USE_STD_ATOMIC )
|
||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_USE_SPINLOCK )
|
||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
|
||||
|
||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ )
|
||||
# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_HAS_SYNC )
|
||||
# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
|
||||
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
|
||||
|
||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||
# include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
|
||||
|
||||
#elif !defined( BOOST_HAS_THREADS )
|
||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
|
||||
|
||||
#else
|
||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
72
include/boost/smart_ptr/detail/atomic_count_gcc.hpp
Normal file
72
include/boost/smart_ptr/detail/atomic_count_gcc.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_gcc.hpp
|
||||
//
|
||||
// atomic_count for GNU libstdc++ v3
|
||||
//
|
||||
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2002 Lars Gullik Bj<42>nnes <larsbj@lyx.org>
|
||||
// Copyright 2003-2005 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)
|
||||
//
|
||||
|
||||
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
|
||||
# include <ext/atomicity.h>
|
||||
#else
|
||||
# include <bits/atomicity.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined(__GLIBCXX__) // g++ 3.4+
|
||||
|
||||
using __gnu_cxx::__atomic_add;
|
||||
using __gnu_cxx::__exchange_and_add;
|
||||
|
||||
#endif
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ) : value_( v ) {}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return __exchange_and_add( &value_, +1 ) + 1;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return __exchange_and_add( &value_, -1 ) - 1;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return __exchange_and_add( &value_, 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
mutable _Atomic_word value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
77
include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp
Normal file
77
include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_gcc_x86.hpp
|
||||
//
|
||||
// atomic_count for g++ on 486+/AMD64
|
||||
//
|
||||
// Copyright 2007 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)
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return atomic_exchange_and_add( &value_, +1 ) + 1;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return atomic_exchange_and_add( &value_, -1 ) - 1;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return atomic_exchange_and_add( &value_, 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
mutable int value_;
|
||||
|
||||
private:
|
||||
|
||||
static int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
// int r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
int r;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"lock\n\t"
|
||||
"xadd %1, %0":
|
||||
"+m"( *pw ), "=r"( r ): // outputs (%0, %1)
|
||||
"1"( dv ): // inputs (%2 == %1)
|
||||
"memory", "cc" // clobbers
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
|
59
include/boost/smart_ptr/detail/atomic_count_nt.hpp
Normal file
59
include/boost/smart_ptr/detail/atomic_count_nt.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_nt.hpp
|
||||
//
|
||||
// Trivial atomic_count for the single-threaded case
|
||||
//
|
||||
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
|
||||
//
|
||||
// Copyright 2013 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
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ): value_( v )
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return ++value_;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return --value_;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
|
97
include/boost/smart_ptr/detail/atomic_count_pt.hpp
Normal file
97
include/boost/smart_ptr/detail/atomic_count_pt.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_pthreads.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// 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/assert.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
//
|
||||
// The generic pthread_mutex-based implementation sometimes leads to
|
||||
// inefficiencies. Example: a class with two atomic_count members
|
||||
// can get away with a single mutex.
|
||||
//
|
||||
// Users can detect this situation by checking BOOST_AC_USE_PTHREADS.
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
private:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
public:
|
||||
|
||||
scoped_lock(pthread_mutex_t & m): m_(m)
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
pthread_mutex_t & m_;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
explicit atomic_count(long v): value_(v)
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 );
|
||||
}
|
||||
|
||||
~atomic_count()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 );
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
scoped_lock lock(mutex_);
|
||||
return ++value_;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
scoped_lock lock(mutex_);
|
||||
return --value_;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
scoped_lock lock(mutex_);
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
mutable pthread_mutex_t mutex_;
|
||||
long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
59
include/boost/smart_ptr/detail/atomic_count_solaris.hpp
Normal file
59
include/boost/smart_ptr/detail/atomic_count_solaris.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_solaris.hpp
|
||||
// based on: boost/detail/atomic_count_win32.hpp
|
||||
//
|
||||
// Copyright (c) 2001-2005 Peter Dimov
|
||||
// Copyright (c) 2006 Michael van der Westhuizen
|
||||
//
|
||||
// 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 <atomic.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( uint32_t v ): value_( v )
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return atomic_inc_32_nv( &value_ );
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return atomic_dec_32_nv( &value_ );
|
||||
}
|
||||
|
||||
operator uint32_t() const
|
||||
{
|
||||
return static_cast<uint32_t const volatile &>( value_ );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count( atomic_count const & );
|
||||
atomic_count & operator=( atomic_count const & );
|
||||
|
||||
uint32_t value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
62
include/boost/smart_ptr/detail/atomic_count_spin.hpp
Normal file
62
include/boost/smart_ptr/detail/atomic_count_spin.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_spin.hpp
|
||||
//
|
||||
// Copyright (c) 2013 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/smart_ptr/detail/spinlock_pool.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ): value_( v )
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
spinlock_pool<0>::scoped_lock lock( &value_ );
|
||||
return ++value_;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
spinlock_pool<0>::scoped_lock lock( &value_ );
|
||||
return --value_;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
spinlock_pool<0>::scoped_lock lock( &value_ );
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
|
60
include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp
Normal file
60
include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_std_atomic.hpp
|
||||
//
|
||||
// atomic_count for std::atomic
|
||||
//
|
||||
// Copyright 2013 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 <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ): value_( v )
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return value_.fetch_add( 1, std::memory_order_acq_rel ) + 1;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return value_.fetch_sub( 1, std::memory_order_acq_rel ) - 1;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return value_.load( std::memory_order_acquire );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
std::atomic_int_least32_t value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
|
61
include/boost/smart_ptr/detail/atomic_count_sync.hpp
Normal file
61
include/boost/smart_ptr/detail/atomic_count_sync.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_sync.hpp
|
||||
//
|
||||
// atomic_count for g++ 4.1+
|
||||
//
|
||||
// http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html
|
||||
//
|
||||
// Copyright 2007 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)
|
||||
//
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ) : value_( v ) {}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return __sync_add_and_fetch( &value_, 1 );
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return __sync_add_and_fetch( &value_, -1 );
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return __sync_fetch_and_add( &value_, 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
mutable long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
63
include/boost/smart_ptr/detail/atomic_count_win32.hpp
Normal file
63
include/boost/smart_ptr/detail/atomic_count_win32.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_win32.hpp
|
||||
//
|
||||
// Copyright (c) 2001-2005 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/smart_ptr/detail/sp_interlocked.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ): value_( v )
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return BOOST_SP_INTERLOCKED_INCREMENT( &value_ );
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return BOOST_SP_INTERLOCKED_DECREMENT( &value_ );
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return static_cast<long const volatile &>( value_ );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count( atomic_count const & );
|
||||
atomic_count & operator=( atomic_count const & );
|
||||
|
||||
long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
42
include/boost/smart_ptr/detail/lightweight_mutex.hpp
Normal file
42
include/boost/smart_ptr/detail/lightweight_mutex.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lightweight_mutex.hpp - lightweight mutex
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// typedef <unspecified> boost::detail::lightweight_mutex;
|
||||
//
|
||||
// boost::detail::lightweight_mutex is a header-only implementation of
|
||||
// a subset of the Mutex concept requirements:
|
||||
//
|
||||
// http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
|
||||
//
|
||||
// It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if !defined(BOOST_HAS_THREADS)
|
||||
# include <boost/smart_ptr/detail/lwm_nop.hpp>
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# include <boost/smart_ptr/detail/lwm_pthreads.hpp>
|
||||
#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# include <boost/smart_ptr/detail/lwm_win32_cs.hpp>
|
||||
#else
|
||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||
# error Unrecognized threading platform
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
37
include/boost/smart_ptr/detail/lwm_nop.hpp
Normal file
37
include/boost/smart_ptr/detail/lwm_nop.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_nop.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
public:
|
||||
|
||||
typedef lightweight_mutex scoped_lock;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
|
87
include/boost/smart_ptr/detail/lwm_pthreads.hpp
Normal file
87
include/boost/smart_ptr/detail/lwm_pthreads.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_pthreads.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// 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/assert.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
pthread_mutex_t m_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
|
||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
|
||||
|
||||
#if defined(__hpux) && defined(_DECTHREADS_)
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
|
||||
#else
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
~lightweight_mutex()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
pthread_mutex_t & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
scoped_lock(lightweight_mutex & m): m_(m.m_)
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
119
include/boost/smart_ptr/detail/lwm_win32_cs.hpp
Normal file
119
include/boost/smart_ptr/detail/lwm_win32_cs.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_win32_cs.hpp
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
// Copyright (c) Microsoft Corporation 2014
|
||||
//
|
||||
// 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/predef.h>
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
struct critical_section
|
||||
{
|
||||
struct critical_section_debug * DebugInfo;
|
||||
long LockCount;
|
||||
long RecursionCount;
|
||||
void * OwningThread;
|
||||
void * LockSemaphore;
|
||||
#if defined(_WIN64)
|
||||
unsigned __int64 SpinCount;
|
||||
#else
|
||||
unsigned long SpinCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(critical_section *, unsigned long, unsigned long);
|
||||
#else
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
|
||||
#endif
|
||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
|
||||
|
||||
#else
|
||||
|
||||
typedef ::CRITICAL_SECTION critical_section;
|
||||
|
||||
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
critical_section cs_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
InitializeCriticalSectionEx(&cs_, 4000, 0);
|
||||
#else
|
||||
InitializeCriticalSection(&cs_);
|
||||
#endif
|
||||
}
|
||||
|
||||
~lightweight_mutex()
|
||||
{
|
||||
DeleteCriticalSection(&cs_);
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
lightweight_mutex & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||
{
|
||||
EnterCriticalSection(&m_.cs_);
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
LeaveCriticalSection(&m_.cs_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
64
include/boost/smart_ptr/detail/operator_bool.hpp
Normal file
64
include/boost/smart_ptr/detail/operator_bool.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
// This header intentionally has no include guards.
|
||||
//
|
||||
// Copyright (c) 2001-2009, 2012 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
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )\
|
||||
&& !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
|
||||
|
||||
explicit operator bool () const BOOST_NOEXCEPT
|
||||
{
|
||||
return px != 0;
|
||||
}
|
||||
|
||||
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
|
||||
|
||||
operator bool () const BOOST_NOEXCEPT
|
||||
{
|
||||
return px != 0;
|
||||
}
|
||||
|
||||
#elif defined( _MANAGED )
|
||||
|
||||
static void unspecified_bool( this_type*** )
|
||||
{
|
||||
}
|
||||
|
||||
typedef void (*unspecified_bool_type)( this_type*** );
|
||||
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: unspecified_bool;
|
||||
}
|
||||
|
||||
#elif \
|
||||
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
|
||||
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
|
||||
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
|
||||
|
||||
typedef element_type * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef element_type * this_type::*unspecified_bool_type;
|
||||
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: &this_type::px;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// operator! is redundant, but some compilers need it
|
||||
bool operator! () const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0;
|
||||
}
|
199
include/boost/smart_ptr/detail/quick_allocator.hpp
Normal file
199
include/boost/smart_ptr/detail/quick_allocator.hpp
Normal file
@@ -0,0 +1,199 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/quick_allocator.hpp
|
||||
//
|
||||
// Copyright (c) 2003 David Abrahams
|
||||
// Copyright (c) 2003 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>
|
||||
|
||||
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
#include <new> // ::operator new, ::operator delete
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<unsigned size, unsigned align_> union freeblock
|
||||
{
|
||||
typedef typename boost::type_with_alignment<align_>::type aligner_type;
|
||||
aligner_type aligner;
|
||||
char bytes[size];
|
||||
freeblock * next;
|
||||
};
|
||||
|
||||
template<unsigned size, unsigned align_> struct allocator_impl
|
||||
{
|
||||
typedef freeblock<size, align_> block;
|
||||
|
||||
// It may seem odd to use such small pages.
|
||||
//
|
||||
// However, on a typical Windows implementation that uses
|
||||
// the OS allocator, "normal size" pages interact with the
|
||||
// "ordinary" operator new, slowing it down dramatically.
|
||||
//
|
||||
// 512 byte pages are handled by the small object allocator,
|
||||
// and don't interfere with ::new.
|
||||
//
|
||||
// The other alternative is to use much bigger pages (1M.)
|
||||
//
|
||||
// It is surprisingly easy to hit pathological behavior by
|
||||
// varying the page size. g++ 2.96 on Red Hat Linux 7.2,
|
||||
// for example, passionately dislikes 496. 512 seems OK.
|
||||
|
||||
#if defined(BOOST_QA_PAGE_SIZE)
|
||||
|
||||
enum { items_per_page = BOOST_QA_PAGE_SIZE / size };
|
||||
|
||||
#else
|
||||
|
||||
enum { items_per_page = 512 / size }; // 1048560 / size
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
|
||||
static lightweight_mutex & mutex()
|
||||
{
|
||||
static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
|
||||
static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
|
||||
return *pm;
|
||||
}
|
||||
|
||||
static lightweight_mutex * mutex_init;
|
||||
|
||||
#endif
|
||||
|
||||
static block * free;
|
||||
static block * page;
|
||||
static unsigned last;
|
||||
|
||||
static inline void * alloc()
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
lightweight_mutex::scoped_lock lock( mutex() );
|
||||
#endif
|
||||
if(block * x = free)
|
||||
{
|
||||
free = x->next;
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(last == items_per_page)
|
||||
{
|
||||
// "Listen to me carefully: there is no memory leak"
|
||||
// -- Scott Meyers, Eff C++ 2nd Ed Item 10
|
||||
page = ::new block[items_per_page];
|
||||
last = 0;
|
||||
}
|
||||
|
||||
return &page[last++];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void * alloc(std::size_t n)
|
||||
{
|
||||
if(n != size) // class-specific new called for a derived object
|
||||
{
|
||||
return ::operator new(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
lightweight_mutex::scoped_lock lock( mutex() );
|
||||
#endif
|
||||
if(block * x = free)
|
||||
{
|
||||
free = x->next;
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(last == items_per_page)
|
||||
{
|
||||
page = ::new block[items_per_page];
|
||||
last = 0;
|
||||
}
|
||||
|
||||
return &page[last++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dealloc(void * pv)
|
||||
{
|
||||
if(pv != 0) // 18.4.1.1/13
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
lightweight_mutex::scoped_lock lock( mutex() );
|
||||
#endif
|
||||
block * pb = static_cast<block *>(pv);
|
||||
pb->next = free;
|
||||
free = pb;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dealloc(void * pv, std::size_t n)
|
||||
{
|
||||
if(n != size) // class-specific delete called for a derived object
|
||||
{
|
||||
::operator delete(pv);
|
||||
}
|
||||
else if(pv != 0) // 18.4.1.1/13
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
lightweight_mutex::scoped_lock lock( mutex() );
|
||||
#endif
|
||||
block * pb = static_cast<block *>(pv);
|
||||
pb->next = free;
|
||||
free = pb;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
|
||||
template<unsigned size, unsigned align_>
|
||||
lightweight_mutex * allocator_impl<size, align_>::mutex_init = &allocator_impl<size, align_>::mutex();
|
||||
|
||||
#endif
|
||||
|
||||
template<unsigned size, unsigned align_>
|
||||
freeblock<size, align_> * allocator_impl<size, align_>::free = 0;
|
||||
|
||||
template<unsigned size, unsigned align_>
|
||||
freeblock<size, align_> * allocator_impl<size, align_>::page = 0;
|
||||
|
||||
template<unsigned size, unsigned align_>
|
||||
unsigned allocator_impl<size, align_>::last = allocator_impl<size, align_>::items_per_page;
|
||||
|
||||
template<class T>
|
||||
struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of<T>::value >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
709
include/boost/smart_ptr/detail/shared_count.hpp
Normal file
709
include/boost/smart_ptr/detail/shared_count.hpp
Normal file
@@ -0,0 +1,709 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/shared_count.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 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)
|
||||
//
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8027 // Functions containing try are not expanded inline
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/smart_ptr/bad_weak_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
// In order to avoid circular dependencies with Boost.TR1
|
||||
// we make sure that our include of <memory> doesn't try to
|
||||
// pull in the TR1 headers: that's why we use this header
|
||||
// rather than including <memory> directly:
|
||||
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
||||
#include <functional> // std::less
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
# include <new> // std::bad_alloc
|
||||
#endif
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace movelib
|
||||
{
|
||||
|
||||
template< class T, class D > class unique_ptr;
|
||||
|
||||
} // namespace movelib
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
int const shared_count_id = 0x2C35F101;
|
||||
int const weak_count_id = 0x298C38A4;
|
||||
|
||||
#endif
|
||||
|
||||
struct sp_nothrow_tag {};
|
||||
|
||||
template< class D > struct sp_inplace_tag
|
||||
{
|
||||
};
|
||||
|
||||
template< class T > class sp_reference_wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Y > void operator()( Y * p ) const
|
||||
{
|
||||
(*t_)( p );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * t_;
|
||||
};
|
||||
|
||||
template< class D > struct sp_convert_reference
|
||||
{
|
||||
typedef D type;
|
||||
};
|
||||
|
||||
template< class D > struct sp_convert_reference< D& >
|
||||
{
|
||||
typedef sp_reference_wrapper< D > type;
|
||||
};
|
||||
|
||||
class weak_count;
|
||||
|
||||
class shared_count
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base * pi_;
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
int id_;
|
||||
#endif
|
||||
|
||||
friend class weak_count;
|
||||
|
||||
public:
|
||||
|
||||
shared_count(): pi_(0) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y> explicit shared_count( Y * p ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_p<Y>( p );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::checked_delete( p );
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_p<Y>( p );
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::checked_delete( p );
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
|
||||
template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
|
||||
#else
|
||||
template<class P, class D> shared_count( P p, D d ): pi_(0)
|
||||
#endif
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
|
||||
typedef Y* P;
|
||||
#endif
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_pd<P, D>(p, d);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
d(p); // delete p
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_pd<P, D>(p, d);
|
||||
|
||||
if(pi_ == 0)
|
||||
{
|
||||
d(p); // delete p
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||
|
||||
template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_pd< P, D >( p );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
D::operator_fn( p ); // delete p
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_pd< P, D >( p );
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
D::operator_fn( p ); // delete p
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||
|
||||
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
typedef sp_counted_impl_pda<P, D, A> impl_type;
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
|
||||
|
||||
#else
|
||||
|
||||
typedef typename A::template rebind< impl_type >::other A2;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
||||
pi_ = pi;
|
||||
std::allocator_traits<A2>::construct( a2, pi, p, d, a );
|
||||
|
||||
#else
|
||||
|
||||
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
||||
|
||||
#endif
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
d( p );
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
||||
pi_ = pi;
|
||||
|
||||
#else
|
||||
|
||||
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||
|
||||
#endif
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
std::allocator_traits<A2>::construct( a2, pi, p, d, a );
|
||||
|
||||
#else
|
||||
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
d( p );
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||
|
||||
template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
typedef sp_counted_impl_pda< P, D, A > impl_type;
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
|
||||
|
||||
#else
|
||||
|
||||
typedef typename A::template rebind< impl_type >::other A2;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
||||
pi_ = pi;
|
||||
std::allocator_traits<A2>::construct( a2, pi, p, a );
|
||||
|
||||
#else
|
||||
|
||||
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
||||
|
||||
#endif
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
D::operator_fn( p );
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
||||
pi_ = pi;
|
||||
|
||||
#else
|
||||
|
||||
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||
|
||||
#endif
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
std::allocator_traits<A2>::construct( a2, pi, p, a );
|
||||
|
||||
#else
|
||||
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
D::operator_fn( p );
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
// auto_ptr<Y> is special cased to provide the strong guarantee
|
||||
|
||||
template<class Y>
|
||||
explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
r.release();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||
|
||||
template<class Y, class D>
|
||||
explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
typedef typename sp_convert_reference<D>::type D2;
|
||||
|
||||
D2 d2( r.get_deleter() );
|
||||
pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
r.release();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y, class D>
|
||||
explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
typedef typename sp_convert_reference<D>::type D2;
|
||||
|
||||
D2 d2( r.get_deleter() );
|
||||
pi_ = new sp_counted_impl_pd< typename boost::movelib::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
r.release();
|
||||
}
|
||||
|
||||
~shared_count() // nothrow
|
||||
{
|
||||
if( pi_ != 0 ) pi_->release();
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
id_ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
shared_count(shared_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if( pi_ != 0 ) pi_->add_ref_copy();
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
shared_count(shared_count && r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
r.pi_ = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
||||
shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
|
||||
|
||||
shared_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if( tmp != 0 ) tmp->add_ref_copy();
|
||||
if( pi_ != 0 ) pi_->release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(shared_count & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
r.pi_ = pi_;
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return pi_ != 0? pi_->use_count(): 0;
|
||||
}
|
||||
|
||||
bool unique() const // nothrow
|
||||
{
|
||||
return use_count() == 1;
|
||||
}
|
||||
|
||||
bool empty() const // nothrow
|
||||
{
|
||||
return pi_ == 0;
|
||||
}
|
||||
|
||||
friend inline bool operator==(shared_count const & a, shared_count const & b)
|
||||
{
|
||||
return a.pi_ == b.pi_;
|
||||
}
|
||||
|
||||
friend inline bool operator<(shared_count const & a, shared_count const & b)
|
||||
{
|
||||
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
|
||||
}
|
||||
|
||||
void * get_deleter( sp_typeinfo const & ti ) const
|
||||
{
|
||||
return pi_? pi_->get_deleter( ti ): 0;
|
||||
}
|
||||
|
||||
void * get_untyped_deleter() const
|
||||
{
|
||||
return pi_? pi_->get_untyped_deleter(): 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class weak_count
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base * pi_;
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
int id_;
|
||||
#endif
|
||||
|
||||
friend class shared_count;
|
||||
|
||||
public:
|
||||
|
||||
weak_count(): pi_(0) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
weak_count(shared_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_add_ref();
|
||||
}
|
||||
|
||||
weak_count(weak_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_add_ref();
|
||||
}
|
||||
|
||||
// Move support
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
weak_count(weak_count && r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
r.pi_ = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
~weak_count() // nothrow
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
id_ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
weak_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
weak_count & operator= (weak_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(weak_count & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
r.pi_ = pi_;
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return pi_ != 0? pi_->use_count(): 0;
|
||||
}
|
||||
|
||||
bool empty() const // nothrow
|
||||
{
|
||||
return pi_ == 0;
|
||||
}
|
||||
|
||||
friend inline bool operator==(weak_count const & a, weak_count const & b)
|
||||
{
|
||||
return a.pi_ == b.pi_;
|
||||
}
|
||||
|
||||
friend inline bool operator<(weak_count const & a, weak_count const & b)
|
||||
{
|
||||
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
|
||||
}
|
||||
};
|
||||
|
||||
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if( pi_ == 0 || !pi_->add_ref_lock() )
|
||||
{
|
||||
boost::throw_exception( boost::bad_weak_ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if( pi_ != 0 && !pi_->add_ref_lock() )
|
||||
{
|
||||
pi_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn .8027 // Functions containing try are not expanded inline
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
92
include/boost/smart_ptr/detail/sp_convertible.hpp
Normal file
92
include/boost/smart_ptr/detail/sp_convertible.hpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_convertible.hpp
|
||||
//
|
||||
// Copyright 2008 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>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
|
||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
|
||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
|
||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< class Y, class T > struct sp_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) };
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_convertible< Y, T[] >
|
||||
{
|
||||
enum _vt { value = false };
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_convertible< Y[], T[] >
|
||||
{
|
||||
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
|
||||
};
|
||||
|
||||
template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
|
||||
{
|
||||
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
|
||||
};
|
||||
|
||||
struct sp_empty
|
||||
{
|
||||
};
|
||||
|
||||
template< bool > struct sp_enable_if_convertible_impl;
|
||||
|
||||
template<> struct sp_enable_if_convertible_impl<true>
|
||||
{
|
||||
typedef sp_empty type;
|
||||
};
|
||||
|
||||
template<> struct sp_enable_if_convertible_impl<false>
|
||||
{
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
93
include/boost/smart_ptr/detail/sp_counted_base.hpp
Normal file
93
include/boost/smart_ptr/detail/sp_counted_base.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base.hpp
|
||||
//
|
||||
// Copyright 2005-2013 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>
|
||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
|
||||
|
||||
#if defined( __clang__ ) && defined( __has_extension )
|
||||
# if __has_extension( __c_atomic__ )
|
||||
# define BOOST_SP_HAS_CLANG_C11_ATOMICS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_THREADS )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_USE_STD_ATOMIC )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_USE_SPINLOCK )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_pt.hpp>
|
||||
|
||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_clang.hpp>
|
||||
|
||||
#elif defined( __SNC__ )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
|
||||
|
||||
#elif defined(__HP_aCC) && defined(__ia64)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
|
||||
|
||||
#elif defined( __IBMCPP__ ) && defined( __powerpc )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
|
||||
|
||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_HAS_SYNC )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
|
||||
|
||||
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
|
||||
|
||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
|
||||
|
||||
#elif defined( _AIX )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
|
||||
|
||||
#elif !defined( BOOST_HAS_THREADS )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#else
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_SP_HAS_CLANG_C11_ATOMICS
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
151
include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
Normal file
151
include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
|
||||
//
|
||||
// Copyright 2007 Baruch Zilber
|
||||
// Copyright 2007 Boris Gubenko
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <machine/sys/inline.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
|
||||
if (1 == r)
|
||||
{
|
||||
_Asm_mf();
|
||||
}
|
||||
|
||||
return r - 1;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int v = *pw;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (0 == v)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
_Asm_mov_to_ar(_AREG_CCV,
|
||||
v,
|
||||
(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
|
||||
int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
|
||||
if (r == v)
|
||||
{
|
||||
return r + 1;
|
||||
}
|
||||
|
||||
v = r;
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
143
include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
Normal file
143
include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
Normal file
@@ -0,0 +1,143 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_aix.hpp
|
||||
// based on: detail/sp_counted_base_w32.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Michael van der Westhuizen
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <builtins.h>
|
||||
#include <sys/atomic_op.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int32_t* pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline int32_t atomic_decrement( int32_t * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int32_t originalValue;
|
||||
|
||||
__lwsync();
|
||||
originalValue = fetch_and_add( pw, -1 );
|
||||
__isync();
|
||||
|
||||
return (originalValue - 1);
|
||||
}
|
||||
|
||||
inline int32_t atomic_conditional_increment( int32_t * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int32_t tmp = fetch_and_add( pw, 0 );
|
||||
for( ;; )
|
||||
{
|
||||
if( tmp == 0 ) return 0;
|
||||
if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int32_t use_count_; // #shared
|
||||
int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
|
140
include/boost/smart_ptr/detail/sp_counted_base_clang.hpp
Normal file
140
include/boost/smart_ptr/detail/sp_counted_base_clang.hpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_clang.hpp - __c11 clang intrinsics
|
||||
//
|
||||
// Copyright (c) 2007, 2013, 2015 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/detail/sp_typeinfo.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
|
||||
|
||||
inline void atomic_increment( atomic_int_least32_t * pw )
|
||||
{
|
||||
__c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
|
||||
}
|
||||
|
||||
inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw )
|
||||
{
|
||||
return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
|
||||
}
|
||||
|
||||
inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
atomic_int_least32_t use_count_; // #shared
|
||||
atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base()
|
||||
{
|
||||
__c11_atomic_init( &use_count_, 1 );
|
||||
__c11_atomic_init( &weak_count_, 1 );
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
171
include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
Normal file
171
include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( register long * pw )
|
||||
{
|
||||
register int a;
|
||||
|
||||
asm
|
||||
{
|
||||
loop:
|
||||
|
||||
lwarx a, 0, pw
|
||||
addi a, a, 1
|
||||
stwcx. a, 0, pw
|
||||
bne- loop
|
||||
}
|
||||
}
|
||||
|
||||
inline long atomic_decrement( register long * pw )
|
||||
{
|
||||
register int a;
|
||||
|
||||
asm
|
||||
{
|
||||
sync
|
||||
|
||||
loop:
|
||||
|
||||
lwarx a, 0, pw
|
||||
addi a, a, -1
|
||||
stwcx. a, 0, pw
|
||||
bne- loop
|
||||
|
||||
isync
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
inline long atomic_conditional_increment( register long * pw )
|
||||
{
|
||||
register int a;
|
||||
|
||||
asm
|
||||
{
|
||||
loop:
|
||||
|
||||
lwarx a, 0, pw
|
||||
cmpwi a, 0
|
||||
beq store
|
||||
|
||||
addi a, a, 1
|
||||
|
||||
store:
|
||||
|
||||
stwcx. a, 0, pw
|
||||
bne- loop
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<long const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
|
159
include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
Normal file
159
include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2005 Rene Rivera
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
// int r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
asm
|
||||
{
|
||||
mov esi, [pw]
|
||||
mov eax, dv
|
||||
lock xadd dword ptr [esi], eax
|
||||
}
|
||||
}
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
//atomic_exchange_and_add( pw, 1 );
|
||||
|
||||
asm
|
||||
{
|
||||
mov esi, [pw]
|
||||
lock inc dword ptr [esi]
|
||||
}
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// int rv = *pw;
|
||||
// if( rv != 0 ) ++*pw;
|
||||
// return rv;
|
||||
|
||||
asm
|
||||
{
|
||||
mov esi, [pw]
|
||||
mov eax, dword ptr [esi]
|
||||
L0:
|
||||
test eax, eax
|
||||
je L1
|
||||
mov ebx, eax
|
||||
inc ebx
|
||||
lock cmpxchg dword ptr [esi], ebx
|
||||
jne L0
|
||||
L1:
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
|
158
include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
Normal file
158
include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
Normal file
@@ -0,0 +1,158 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2006 Peter Dimov
|
||||
// Copyright 2005 Ben Hutchings
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
int tmp;
|
||||
|
||||
// No barrier is required here but fetchadd always has an acquire or
|
||||
// release barrier associated with it. We choose release as it should be
|
||||
// cheaper.
|
||||
__asm__ ("fetchadd4.rel %0=%1,1" :
|
||||
"=r"(tmp), "=m"(*pw) :
|
||||
"m"( *pw ));
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int rv;
|
||||
|
||||
__asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
|
||||
" cmp.eq p7,p0=1,%0 ;; \n"
|
||||
"(p7) ld4.acq %0=%1 " :
|
||||
"=&r"(rv), "=m"(*pw) :
|
||||
"m"( *pw ) :
|
||||
"p7");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int rv, tmp, tmp2;
|
||||
|
||||
__asm__ ("0: ld4 %0=%3 ;; \n"
|
||||
" cmp.eq p7,p0=0,%0 ;; \n"
|
||||
"(p7) br.cond.spnt 1f \n"
|
||||
" mov ar.ccv=%0 \n"
|
||||
" add %1=1,%0 ;; \n"
|
||||
" cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
|
||||
" cmp.ne p7,p0=%0,%2 ;; \n"
|
||||
"(p7) br.cond.spnt 0b \n"
|
||||
" mov %0=%1 ;; \n"
|
||||
"1:" :
|
||||
"=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
|
||||
"m"( *pw ) :
|
||||
"ar.ccv", "p7");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
|
182
include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
Normal file
182
include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
Normal file
@@ -0,0 +1,182 @@
|
||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
|
||||
//
|
||||
// Copyright (c) 2009, Spirent Communications, Inc.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
int tmp;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"0:\n\t"
|
||||
".set push\n\t"
|
||||
".set mips2\n\t"
|
||||
"ll %0, %1\n\t"
|
||||
"addiu %0, 1\n\t"
|
||||
"sc %0, %1\n\t"
|
||||
".set pop\n\t"
|
||||
"beqz %0, 0b":
|
||||
"=&r"( tmp ), "=m"( *pw ):
|
||||
"m"( *pw )
|
||||
);
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int rv, tmp;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"0:\n\t"
|
||||
".set push\n\t"
|
||||
".set mips2\n\t"
|
||||
"ll %1, %2\n\t"
|
||||
"addiu %0, %1, -1\n\t"
|
||||
"sc %0, %2\n\t"
|
||||
".set pop\n\t"
|
||||
"beqz %0, 0b\n\t"
|
||||
"addiu %0, %1, -1":
|
||||
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
|
||||
"m"( *pw ):
|
||||
"memory"
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int rv, tmp;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"0:\n\t"
|
||||
".set push\n\t"
|
||||
".set mips2\n\t"
|
||||
"ll %0, %2\n\t"
|
||||
"beqz %0, 1f\n\t"
|
||||
"addiu %1, %0, 1\n\t"
|
||||
"sc %1, %2\n\t"
|
||||
".set pop\n\t"
|
||||
"beqz %1, 0b\n\t"
|
||||
"addiu %0, %0, 1\n\t"
|
||||
"1:":
|
||||
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
|
||||
"m"( *pw ):
|
||||
"memory"
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
|
182
include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
Normal file
182
include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
Normal file
@@ -0,0 +1,182 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
int tmp;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"0:\n\t"
|
||||
"lwarx %1, 0, %2\n\t"
|
||||
"addi %1, %1, 1\n\t"
|
||||
"stwcx. %1, 0, %2\n\t"
|
||||
"bne- 0b":
|
||||
|
||||
"=m"( *pw ), "=&b"( tmp ):
|
||||
"r"( pw ), "m"( *pw ):
|
||||
"cc"
|
||||
);
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int rv;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"sync\n\t"
|
||||
"0:\n\t"
|
||||
"lwarx %1, 0, %2\n\t"
|
||||
"addi %1, %1, -1\n\t"
|
||||
"stwcx. %1, 0, %2\n\t"
|
||||
"bne- 0b\n\t"
|
||||
"isync":
|
||||
|
||||
"=m"( *pw ), "=&b"( rv ):
|
||||
"r"( pw ), "m"( *pw ):
|
||||
"memory", "cc"
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int rv;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"0:\n\t"
|
||||
"lwarx %1, 0, %2\n\t"
|
||||
"cmpwi %1, 0\n\t"
|
||||
"beq 1f\n\t"
|
||||
"addi %1, %1, 1\n\t"
|
||||
"1:\n\t"
|
||||
"stwcx. %1, 0, %2\n\t"
|
||||
"bne- 0b":
|
||||
|
||||
"=m"( *pw ), "=&b"( rv ):
|
||||
"r"( pw ), "m"( *pw ):
|
||||
"cc"
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
|
167
include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
Normal file
167
include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
Normal file
@@ -0,0 +1,167 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
|
||||
//
|
||||
// Copyright (c) 2006 Piotr Wyderski
|
||||
// Copyright (c) 2006 Tomas Puverle
|
||||
// Copyright (c) 2006 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
|
||||
//
|
||||
// Thanks to Michael van der Westhuizen
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <inttypes.h> // int32_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
|
||||
{
|
||||
__asm__ __volatile__( "cas [%1], %2, %0"
|
||||
: "+r" (swap_)
|
||||
: "r" (dest_), "r" (compare_)
|
||||
: "memory" );
|
||||
|
||||
return swap_;
|
||||
}
|
||||
|
||||
inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
|
||||
{
|
||||
// long r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
int32_t r = *pw;
|
||||
|
||||
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void atomic_increment( int32_t * pw )
|
||||
{
|
||||
atomic_fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline int32_t atomic_decrement( int32_t * pw )
|
||||
{
|
||||
return atomic_fetch_and_add( pw, -1 );
|
||||
}
|
||||
|
||||
inline int32_t atomic_conditional_increment( int32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
int32_t r = *pw;
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int32_t use_count_; // #shared
|
||||
int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< int32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
174
include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
Normal file
174
include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
// int r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
int r;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"lock\n\t"
|
||||
"xadd %1, %0":
|
||||
"=m"( *pw ), "=r"( r ): // outputs (%0, %1)
|
||||
"m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
|
||||
"memory", "cc" // clobbers
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
//atomic_exchange_and_add( pw, 1 );
|
||||
|
||||
__asm__
|
||||
(
|
||||
"lock\n\t"
|
||||
"incl %0":
|
||||
"=m"( *pw ): // output (%0)
|
||||
"m"( *pw ): // input (%1)
|
||||
"cc" // clobbers
|
||||
);
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// int rv = *pw;
|
||||
// if( rv != 0 ) ++*pw;
|
||||
// return rv;
|
||||
|
||||
int rv, tmp;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"movl %0, %%eax\n\t"
|
||||
"0:\n\t"
|
||||
"test %%eax, %%eax\n\t"
|
||||
"je 1f\n\t"
|
||||
"movl %%eax, %2\n\t"
|
||||
"incl %2\n\t"
|
||||
"lock\n\t"
|
||||
"cmpxchgl %2, %0\n\t"
|
||||
"jne 0b\n\t"
|
||||
"1:":
|
||||
"=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
|
||||
"m"( *pw ): // input (%3)
|
||||
"cc" // clobbers
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
|
108
include/boost/smart_ptr/detail/sp_counted_base_nt.hpp
Normal file
108
include/boost/smart_ptr/detail/sp_counted_base_nt.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_nt.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 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/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
++use_count_;
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
if( use_count_ == 0 ) return false;
|
||||
++use_count_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( --use_count_ == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
++weak_count_;
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( --weak_count_ == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return use_count_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
137
include/boost/smart_ptr/detail/sp_counted_base_pt.hpp
Normal file
137
include/boost/smart_ptr/detail/sp_counted_base_pt.hpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_pt.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 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/detail/sp_typeinfo.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
mutable pthread_mutex_t m_;
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
|
||||
|
||||
#if defined(__hpux) && defined(_DECTHREADS_)
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
|
||||
#else
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
++use_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
bool r = use_count_ == 0? false: ( ++use_count_, true );
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
return r;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long new_use_count = --use_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
if( new_use_count == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
++weak_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long new_weak_count = --weak_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
if( new_weak_count == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long r = use_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
162
include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
Normal file
162
include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
Normal file
@@ -0,0 +1,162 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
|
||||
//
|
||||
// Copyright (c) 2006 Piotr Wyderski
|
||||
// Copyright (c) 2006 Tomas Puverle
|
||||
// Copyright (c) 2006 Peter Dimov
|
||||
// Copyright (c) 2011 Emil Dotchevski
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// Thanks to Michael van der Westhuizen
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <inttypes.h> // uint32_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
|
||||
{
|
||||
return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
|
||||
}
|
||||
|
||||
inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
|
||||
{
|
||||
// long r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
uint32_t r = *pw;
|
||||
|
||||
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void atomic_increment( uint32_t * pw )
|
||||
{
|
||||
(void) __builtin_cellAtomicIncr32( pw );
|
||||
}
|
||||
|
||||
inline uint32_t atomic_decrement( uint32_t * pw )
|
||||
{
|
||||
return __builtin_cellAtomicDecr32( pw );
|
||||
}
|
||||
|
||||
inline uint32_t atomic_conditional_increment( uint32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
uint32_t r = *pw;
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
uint32_t use_count_; // #shared
|
||||
uint32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< uint32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
114
include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
Normal file
114
include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_solaris.hpp
|
||||
// based on: detail/sp_counted_base_w32.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Michael van der Westhuizen
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <atomic.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
uint32_t use_count_; // #shared
|
||||
uint32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_inc_32( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
|
||||
if( tmp == 0 ) return false;
|
||||
if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
|
||||
}
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_dec_32_nv( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_inc_32( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_dec_32_nv( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<long const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
132
include/boost/smart_ptr/detail/sp_counted_base_spin.hpp
Normal file
132
include/boost/smart_ptr/detail/sp_counted_base_spin.hpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2008 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/detail/sp_typeinfo.hpp>
|
||||
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
|
||||
int r = *pw;
|
||||
*pw += dv;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
++*pw;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
|
||||
int rv = *pw;
|
||||
if( rv != 0 ) ++*pw;
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( &use_count_ );
|
||||
return use_count_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
137
include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
Normal file
137
include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_std_atomic.hpp - C++11 std::atomic
|
||||
//
|
||||
// Copyright (c) 2007, 2013 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/detail/sp_typeinfo.hpp>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( std::atomic_int_least32_t * pw )
|
||||
{
|
||||
pw->fetch_add( 1, std::memory_order_relaxed );
|
||||
}
|
||||
|
||||
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw )
|
||||
{
|
||||
return pw->fetch_sub( 1, std::memory_order_acq_rel );
|
||||
}
|
||||
|
||||
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
std::int_least32_t r = pw->load( std::memory_order_relaxed );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
std::atomic_int_least32_t use_count_; // #shared
|
||||
std::atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return use_count_.load( std::memory_order_acquire );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
|
156
include/boost/smart_ptr/detail/sp_counted_base_sync.hpp
Normal file
156
include/boost/smart_ptr/detail/sp_counted_base_sync.hpp
Normal file
@@ -0,0 +1,156 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
|
||||
//
|
||||
// Copyright (c) 2007 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/detail/sp_typeinfo.hpp>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if INT_MAX >= 2147483647
|
||||
|
||||
typedef int sp_int32_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef long sp_int32_t;
|
||||
|
||||
#endif
|
||||
|
||||
inline void atomic_increment( sp_int32_t * pw )
|
||||
{
|
||||
__sync_fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline sp_int32_t atomic_decrement( sp_int32_t * pw )
|
||||
{
|
||||
return __sync_fetch_and_add( pw, -1 );
|
||||
}
|
||||
|
||||
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
sp_int32_t r = *pw;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
|
||||
|
||||
if( r2 == r )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = r2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
sp_int32_t use_count_; // #shared
|
||||
sp_int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< sp_int32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
151
include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
Normal file
151
include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
|
||||
// based on: detail/sp_counted_base_w32.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Michael van der Westhuizen
|
||||
// Copyright 2012 IBM Corp.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
extern "builtin" void __lwsync(void);
|
||||
extern "builtin" void __isync(void);
|
||||
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
|
||||
extern "builtin" int __compare_and_swap(volatile int*, int*, int);
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int *pw )
|
||||
{
|
||||
// ++*pw;
|
||||
__lwsync();
|
||||
__fetch_and_add(pw, 1);
|
||||
__isync();
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int *pw )
|
||||
{
|
||||
// return --*pw;
|
||||
__lwsync();
|
||||
int originalValue = __fetch_and_add(pw, -1);
|
||||
__isync();
|
||||
|
||||
return (originalValue - 1);
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int *pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
__lwsync();
|
||||
int v = *const_cast<volatile int*>(pw);
|
||||
for (;;)
|
||||
// loop until state is known
|
||||
{
|
||||
if (v == 0) return 0;
|
||||
if (__compare_and_swap(pw, &v, v + 1))
|
||||
{
|
||||
__isync(); return (v + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
char pad[64] __attribute__((__aligned__(64)));
|
||||
// pad to prevent false sharing
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return *const_cast<volatile int*>(&use_count_);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
131
include/boost/smart_ptr/detail/sp_counted_base_w32.hpp
Normal file
131
include/boost/smart_ptr/detail/sp_counted_base_w32.hpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_w32.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 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)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
long tmp = static_cast< long const volatile& >( use_count_ );
|
||||
if( tmp == 0 ) return false;
|
||||
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
|
||||
|
||||
// work around a code generation bug
|
||||
|
||||
long tmp2 = tmp + 1;
|
||||
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
|
||||
|
||||
#else
|
||||
|
||||
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( BOOST_SP_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<long const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
271
include/boost/smart_ptr/detail/sp_counted_impl.hpp
Normal file
271
include/boost/smart_ptr/detail/sp_counted_impl.hpp
Normal file
@@ -0,0 +1,271 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_impl.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 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_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
|
||||
#endif
|
||||
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
#include <boost/smart_ptr/detail/quick_allocator.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
#include <memory> // std::allocator
|
||||
#endif
|
||||
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
|
||||
void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
|
||||
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class X> class sp_counted_impl_p: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
X * px_;
|
||||
|
||||
sp_counted_impl_p( sp_counted_impl_p const & );
|
||||
sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
|
||||
|
||||
typedef sp_counted_impl_p<X> this_type;
|
||||
|
||||
public:
|
||||
|
||||
explicit sp_counted_impl_p( X * px ): px_( px )
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook( px, sizeof(X), this );
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
|
||||
#endif
|
||||
boost::checked_delete( px_ );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
{
|
||||
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
{
|
||||
return quick_allocator<this_type>::alloc();
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
quick_allocator<this_type>::dealloc( p );
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
// Borland's Codeguard trips up over the -Vx- option here:
|
||||
//
|
||||
#ifdef __CODEGUARD__
|
||||
# pragma option push -Vx-
|
||||
#endif
|
||||
|
||||
template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
P ptr; // copy constructor must not throw
|
||||
D del; // copy constructor must not throw
|
||||
|
||||
sp_counted_impl_pd( sp_counted_impl_pd const & );
|
||||
sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
|
||||
|
||||
typedef sp_counted_impl_pd<P, D> this_type;
|
||||
|
||||
public:
|
||||
|
||||
// pre: d(p) must not throw
|
||||
|
||||
sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
|
||||
{
|
||||
}
|
||||
|
||||
sp_counted_impl_pd( P p ): ptr( p ), del()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
{
|
||||
del( ptr );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return &reinterpret_cast<char&>( del );
|
||||
}
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
{
|
||||
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
{
|
||||
return quick_allocator<this_type>::alloc();
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
quick_allocator<this_type>::dealloc( p );
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
P p_; // copy constructor must not throw
|
||||
D d_; // copy constructor must not throw
|
||||
A a_; // copy constructor must not throw
|
||||
|
||||
sp_counted_impl_pda( sp_counted_impl_pda const & );
|
||||
sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
|
||||
|
||||
typedef sp_counted_impl_pda<P, D, A> this_type;
|
||||
|
||||
public:
|
||||
|
||||
// pre: d( p ) must not throw
|
||||
|
||||
sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
|
||||
{
|
||||
}
|
||||
|
||||
sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
{
|
||||
d_( p_ );
|
||||
}
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
|
||||
|
||||
#else
|
||||
|
||||
typedef typename A::template rebind< this_type >::other A2;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a_ );
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
std::allocator_traits<A2>::destroy( a2, this );
|
||||
|
||||
#else
|
||||
|
||||
this->~this_type();
|
||||
|
||||
#endif
|
||||
|
||||
a2.deallocate( this, 1 );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return &reinterpret_cast<char&>( d_ );
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __CODEGUARD__
|
||||
# pragma option pop
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
40
include/boost/smart_ptr/detail/sp_disable_deprecated.hpp
Normal file
40
include/boost/smart_ptr/detail/sp_disable_deprecated.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/smart_ptr/detail/sp_disable_deprecated.hpp
|
||||
//
|
||||
// Copyright 2015 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( __GNUC__ ) && ( defined( __GXX_EXPERIMENTAL_CXX0X__ ) || ( __cplusplus >= 201103L ) )
|
||||
|
||||
# if defined( BOOST_GCC )
|
||||
|
||||
# if BOOST_GCC >= 40600
|
||||
# define BOOST_SP_DISABLE_DEPRECATED
|
||||
# endif
|
||||
|
||||
# elif defined( __clang__ ) && defined( __has_warning )
|
||||
|
||||
# if __has_warning( "-Wdeprecated-declarations" )
|
||||
# define BOOST_SP_DISABLE_DEPRECATED
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
52
include/boost/smart_ptr/detail/sp_forward.hpp
Normal file
52
include/boost/smart_ptr/detail/sp_forward.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_forward.hpp
|
||||
//
|
||||
// Copyright 2008,2012 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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
#if defined( BOOST_GCC ) && __GNUC__ * 100 + __GNUC_MINOR__ <= 404
|
||||
|
||||
// GCC 4.4 supports an outdated version of rvalue references and creates a copy of the forwarded object.
|
||||
// This results in warnings 'returning reference to temporary'. Therefore we use a special version similar to std::forward.
|
||||
template< class T > T&& sp_forward( T && t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< T&& >( t );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
69
include/boost/smart_ptr/detail/sp_has_sync.hpp
Normal file
69
include/boost/smart_ptr/detail/sp_has_sync.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/smart_ptr/detail/sp_has_sync.hpp
|
||||
//
|
||||
// Copyright (c) 2008, 2009 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)
|
||||
//
|
||||
// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics
|
||||
// are available.
|
||||
//
|
||||
|
||||
#ifndef BOOST_SP_NO_SYNC
|
||||
|
||||
#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
|
||||
|
||||
# define BOOST_SP_HAS_SYNC
|
||||
|
||||
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
|
||||
|
||||
# define BOOST_SP_HAS_SYNC
|
||||
|
||||
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
||||
|
||||
#define BOOST_SP_HAS_SYNC
|
||||
|
||||
#if defined( __arm__ ) || defined( __armel__ )
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#if defined( __hppa ) || defined( __hppa__ )
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#if defined( __m68k__ )
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#if defined( __sh__ )
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#if defined( __sparc__ )
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SP_NO_SYNC
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
|
34
include/boost/smart_ptr/detail/sp_if_array.hpp
Normal file
34
include/boost/smart_ptr/detail/sp_if_array.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<class T>
|
||||
struct sp_if_array;
|
||||
|
||||
template<class T>
|
||||
struct sp_if_array<T[]> {
|
||||
typedef boost::shared_ptr<T[]> type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct sp_if_size_array;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct sp_if_size_array<T[N]> {
|
||||
typedef boost::shared_ptr<T[N]> type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
163
include/boost/smart_ptr/detail/sp_interlocked.hpp
Normal file
163
include/boost/smart_ptr/detail/sp_interlocked.hpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/sp_interlocked.hpp
|
||||
//
|
||||
// Copyright 2005, 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>
|
||||
|
||||
// BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// VC9 has intrin.h, but it collides with <utility>
|
||||
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600
|
||||
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets.
|
||||
#elif defined( __MINGW64_VERSION_MAJOR )
|
||||
|
||||
// MinGW-w64 provides intrin.h for both 32 and 64-bit targets.
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// Intel C++ on Windows on VC10+ stdlib
|
||||
#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
|
||||
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
|
||||
|
||||
#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H )
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#elif defined( _WIN32_WCE )
|
||||
|
||||
#if _WIN32_WCE >= 0x600
|
||||
|
||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#else
|
||||
|
||||
// under Windows CE we still have old-style Interlocked* functions
|
||||
|
||||
extern "C" long __cdecl InterlockedIncrement( long* );
|
||||
extern "C" long __cdecl InterlockedDecrement( long* );
|
||||
extern "C" long __cdecl InterlockedCompareExchange( long*, long, long );
|
||||
extern "C" long __cdecl InterlockedExchange( long*, long );
|
||||
extern "C" long __cdecl InterlockedExchangeAdd( long*, long );
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN )
|
||||
|
||||
#if defined( __CLRCALL_PURE_OR_CDECL )
|
||||
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
#else
|
||||
|
||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
# if defined( BOOST_MSVC ) && BOOST_MSVC == 1310
|
||||
//From MSDN, Visual Studio .NET 2003 spedific: To declare one of the interlocked functions
|
||||
//for use as an intrinsic, the function must be declared with the leading underscore and
|
||||
//the new function must appear in a #pragma intrinsic statement.
|
||||
# pragma intrinsic( _InterlockedIncrement )
|
||||
# pragma intrinsic( _InterlockedDecrement )
|
||||
# pragma intrinsic( _InterlockedCompareExchange )
|
||||
# pragma intrinsic( _InterlockedExchange )
|
||||
# pragma intrinsic( _InterlockedExchangeAdd )
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd
|
||||
|
||||
#else
|
||||
|
||||
# error "Interlocked intrinsics not available"
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
45
include/boost/smart_ptr/detail/sp_nullptr_t.hpp
Normal file
45
include/boost/smart_ptr/detail/sp_nullptr_t.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_nullptr_t.hpp
|
||||
//
|
||||
// Copyright 2013 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>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
|
||||
|
||||
typedef decltype(nullptr) sp_nullptr_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef std::nullptr_t sp_nullptr_t;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
65
include/boost/smart_ptr/detail/spinlock.hpp
Normal file
65
include/boost/smart_ptr/detail/spinlock.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/spinlock.hpp
|
||||
//
|
||||
// Copyright (c) 2008 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)
|
||||
//
|
||||
// struct spinlock
|
||||
// {
|
||||
// void lock();
|
||||
// bool try_lock();
|
||||
// void unlock();
|
||||
//
|
||||
// class scoped_lock;
|
||||
// };
|
||||
//
|
||||
// #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
|
||||
|
||||
#if defined( BOOST_SP_USE_STD_ATOMIC )
|
||||
# if !defined( __clang__ )
|
||||
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
|
||||
# else
|
||||
// Clang (at least up to 3.4) can't compile spinlock_pool when
|
||||
// using std::atomic, so substitute the __sync implementation instead.
|
||||
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
|
||||
# endif
|
||||
|
||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
|
||||
|
||||
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
|
||||
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_HAS_SYNC )
|
||||
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
|
||||
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# include <boost/smart_ptr/detail/spinlock_w32.hpp>
|
||||
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
|
||||
|
||||
#elif !defined(BOOST_HAS_THREADS)
|
||||
# include <boost/smart_ptr/detail/spinlock_nt.hpp>
|
||||
|
||||
#else
|
||||
# error Unrecognized threading platform
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
121
include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
Normal file
121
include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// Copyright (c) 2008, 2011 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/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER "dmb"
|
||||
# define BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
|
||||
# define BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER ""
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
int v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int r;
|
||||
|
||||
#ifdef BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
__asm__ __volatile__(
|
||||
"ldrex %0, [%2]; \n"
|
||||
"cmp %0, %1; \n"
|
||||
"strexne %0, %1, [%2]; \n"
|
||||
BOOST_SP_ARM_BARRIER :
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
#else
|
||||
|
||||
__asm__ __volatile__(
|
||||
"swp %0, %1, [%2];\n"
|
||||
BOOST_SP_ARM_BARRIER :
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
#endif
|
||||
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||
*const_cast< int volatile* >( &v_ ) = 0;
|
||||
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#undef BOOST_SP_ARM_BARRIER
|
||||
#undef BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
89
include/boost/smart_ptr/detail/spinlock_nt.hpp
Normal file
89
include/boost/smart_ptr/detail/spinlock_nt.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 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/assert.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
bool locked_;
|
||||
|
||||
public:
|
||||
|
||||
inline bool try_lock()
|
||||
{
|
||||
if( locked_ )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
locked_ = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void lock()
|
||||
{
|
||||
BOOST_ASSERT( !locked_ );
|
||||
locked_ = true;
|
||||
}
|
||||
|
||||
inline void unlock()
|
||||
{
|
||||
BOOST_ASSERT( locked_ );
|
||||
locked_ = false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { false }
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
91
include/boost/smart_ptr/detail/spinlock_pool.hpp
Normal file
91
include/boost/smart_ptr/detail/spinlock_pool.hpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/spinlock_pool.hpp
|
||||
//
|
||||
// Copyright (c) 2008 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)
|
||||
//
|
||||
// spinlock_pool<0> is reserved for atomic<>, when/if it arrives
|
||||
// spinlock_pool<1> is reserved for shared_ptr reference counts
|
||||
// spinlock_pool<2> is reserved for shared_ptr atomic access
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/spinlock.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< int M > class spinlock_pool
|
||||
{
|
||||
private:
|
||||
|
||||
static spinlock pool_[ 41 ];
|
||||
|
||||
public:
|
||||
|
||||
static spinlock & spinlock_for( void const * pv )
|
||||
{
|
||||
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
|
||||
std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
|
||||
#else
|
||||
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
|
||||
#endif
|
||||
return pool_[ i ];
|
||||
}
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
|
||||
{
|
||||
sp_.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template< int M > spinlock spinlock_pool< M >::pool_[ 41 ] =
|
||||
{
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
79
include/boost/smart_ptr/detail/spinlock_pt.hpp
Normal file
79
include/boost/smart_ptr/detail/spinlock_pt.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 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 <pthread.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
pthread_mutex_t v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return pthread_mutex_trylock( &v_ ) == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
pthread_mutex_lock( &v_ );
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
pthread_mutex_unlock( &v_ );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
83
include/boost/smart_ptr/detail/spinlock_std_atomic.hpp
Normal file
83
include/boost/smart_ptr/detail/spinlock_std_atomic.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 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/smart_ptr/detail/yield_k.hpp>
|
||||
#include <atomic>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
std::atomic_flag v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return !v_.test_and_set( std::memory_order_acquire );
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
v_ .clear( std::memory_order_release );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT }
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
87
include/boost/smart_ptr/detail/spinlock_sync.hpp
Normal file
87
include/boost/smart_ptr/detail/spinlock_sync.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 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/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
int v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int r = __sync_lock_test_and_set( &v_, 1 );
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
__sync_lock_release( &v_ );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
113
include/boost/smart_ptr/detail/spinlock_w32.hpp
Normal file
113
include/boost/smart_ptr/detail/spinlock_w32.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 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/smart_ptr/detail/sp_interlocked.hpp>
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
// BOOST_COMPILER_FENCE
|
||||
|
||||
#if defined(__INTEL_COMPILER)
|
||||
|
||||
#define BOOST_COMPILER_FENCE __memory_barrier();
|
||||
|
||||
#elif defined( _MSC_VER ) && _MSC_VER >= 1310
|
||||
|
||||
extern "C" void _ReadWriteBarrier();
|
||||
#pragma intrinsic( _ReadWriteBarrier )
|
||||
|
||||
#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_COMPILER_FENCE
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
long v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 );
|
||||
|
||||
BOOST_COMPILER_FENCE
|
||||
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
BOOST_COMPILER_FENCE
|
||||
*const_cast< long volatile* >( &v_ ) = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
177
include/boost/smart_ptr/detail/yield_k.hpp
Normal file
177
include/boost/smart_ptr/detail/yield_k.hpp
Normal file
@@ -0,0 +1,177 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// yield_k.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
// Copyright (c) Microsoft Corporation 2014
|
||||
//
|
||||
// void yield( unsigned k );
|
||||
//
|
||||
// Typical use:
|
||||
//
|
||||
// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
|
||||
//
|
||||
// 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>
|
||||
#include <boost/predef.h>
|
||||
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
// BOOST_SMT_PAUSE
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
|
||||
|
||||
extern "C" void _mm_pause();
|
||||
|
||||
#define BOOST_SMT_PAUSE _mm_pause();
|
||||
|
||||
#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
|
||||
|
||||
#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
#if !BOOST_COMP_CLANG || !defined __MINGW32__
|
||||
extern "C" void __stdcall Sleep( unsigned long ms );
|
||||
#else
|
||||
#include <_mingw.h>
|
||||
#if !defined __MINGW64_VERSION_MAJOR
|
||||
extern "C" void __stdcall Sleep( unsigned long ms );
|
||||
#else
|
||||
extern "C" __declspec(dllimport) void __stdcall Sleep( unsigned long ms );
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline void yield( unsigned k )
|
||||
{
|
||||
if( k < 4 )
|
||||
{
|
||||
}
|
||||
#if defined( BOOST_SMT_PAUSE )
|
||||
else if( k < 16 )
|
||||
{
|
||||
BOOST_SMT_PAUSE
|
||||
}
|
||||
#endif
|
||||
#if !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
else if( k < 32 )
|
||||
{
|
||||
Sleep( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sleep( 1 );
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
// Sleep isn't supported on the Windows Runtime.
|
||||
std::this_thread::yield();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#elif defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
#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
|
||||
|
||||
#include <time.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void yield( unsigned k )
|
||||
{
|
||||
if( k < 4 )
|
||||
{
|
||||
}
|
||||
#if defined( BOOST_SMT_PAUSE )
|
||||
else if( k < 16 )
|
||||
{
|
||||
BOOST_SMT_PAUSE
|
||||
}
|
||||
#endif
|
||||
else if( k < 32 || k & 1 )
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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 );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void yield( unsigned )
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
165
include/boost/smart_ptr/enable_shared_from_raw.hpp
Normal file
165
include/boost/smart_ptr/enable_shared_from_raw.hpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
||||
#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// enable_shared_from_raw.hpp
|
||||
//
|
||||
// Copyright 2002, 2009, 2014 Peter Dimov
|
||||
// Copyright 2008-2009 Frank Mori Hess
|
||||
//
|
||||
// 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>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
|
||||
template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class enable_shared_from_raw
|
||||
{
|
||||
protected:
|
||||
|
||||
enable_shared_from_raw()
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_raw( enable_shared_from_raw const & )
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_raw & operator=( enable_shared_from_raw const & )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~enable_shared_from_raw()
|
||||
{
|
||||
BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init_if_expired() const
|
||||
{
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
||||
weak_this_ = shared_this_;
|
||||
}
|
||||
}
|
||||
|
||||
void init_if_empty() const
|
||||
{
|
||||
if( weak_this_._empty() )
|
||||
{
|
||||
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
||||
weak_this_ = shared_this_;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
template<class Y> friend class shared_ptr;
|
||||
template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
|
||||
template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
|
||||
template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||
#endif
|
||||
|
||||
shared_ptr<void const volatile> shared_from_this() const
|
||||
{
|
||||
init_if_expired();
|
||||
return shared_ptr<void const volatile>( weak_this_ );
|
||||
}
|
||||
|
||||
shared_ptr<void const volatile> shared_from_this() const volatile
|
||||
{
|
||||
return const_cast< enable_shared_from_raw const * >( this )->shared_from_this();
|
||||
}
|
||||
|
||||
weak_ptr<void const volatile> weak_from_this() const
|
||||
{
|
||||
init_if_empty();
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
weak_ptr<void const volatile> weak_from_this() const volatile
|
||||
{
|
||||
return const_cast< enable_shared_from_raw const * >( this )->weak_from_this();
|
||||
}
|
||||
|
||||
// Note: invoked automatically by shared_ptr; do not call
|
||||
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * ) const
|
||||
{
|
||||
BOOST_ASSERT( ppx != 0 );
|
||||
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
weak_this_ = *ppx;
|
||||
}
|
||||
else if( shared_this_.use_count() != 0 )
|
||||
{
|
||||
BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
|
||||
|
||||
detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
|
||||
BOOST_ASSERT( pd != 0 );
|
||||
|
||||
pd->set_deleter( *ppx );
|
||||
|
||||
ppx->reset( shared_this_, ppx->get() );
|
||||
shared_this_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
mutable weak_ptr<void const volatile> weak_this_;
|
||||
|
||||
private:
|
||||
|
||||
mutable shared_ptr<void const volatile> shared_this_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<T> shared_from_raw(T *p)
|
||||
{
|
||||
BOOST_ASSERT(p != 0);
|
||||
return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
boost::weak_ptr<T> weak_from_raw(T *p)
|
||||
{
|
||||
BOOST_ASSERT(p != 0);
|
||||
boost::weak_ptr<T> result;
|
||||
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_from_this(), p);
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe )
|
||||
{
|
||||
if( pe != 0 )
|
||||
{
|
||||
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
|
||||
}
|
||||
}
|
||||
} // namepsace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
89
include/boost/smart_ptr/enable_shared_from_this.hpp
Normal file
89
include/boost/smart_ptr/enable_shared_from_this.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// enable_shared_from_this.hpp
|
||||
//
|
||||
// Copyright 2002, 2009 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
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/weak_ptr.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class enable_shared_from_this
|
||||
{
|
||||
protected:
|
||||
|
||||
enable_shared_from_this() BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
shared_ptr<T> shared_from_this()
|
||||
{
|
||||
shared_ptr<T> p( weak_this_ );
|
||||
BOOST_ASSERT( p.get() == this );
|
||||
return p;
|
||||
}
|
||||
|
||||
shared_ptr<T const> shared_from_this() const
|
||||
{
|
||||
shared_ptr<T const> p( weak_this_ );
|
||||
BOOST_ASSERT( p.get() == this );
|
||||
return p;
|
||||
}
|
||||
|
||||
weak_ptr<T> weak_from_this() BOOST_NOEXCEPT
|
||||
{
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
weak_ptr<T const> weak_from_this() const BOOST_NOEXCEPT
|
||||
{
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
public: // actually private, but avoids compiler template friendship issues
|
||||
|
||||
// Note: invoked automatically by shared_ptr; do not call
|
||||
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
|
||||
{
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
weak_this_ = shared_ptr<T>( *ppx, py );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mutable weak_ptr<T> weak_this_;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
360
include/boost/smart_ptr/intrusive_ptr.hpp
Normal file
360
include/boost/smart_ptr/intrusive_ptr.hpp
Normal file
@@ -0,0 +1,360 @@
|
||||
#ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// intrusive_ptr.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
|
||||
#include <boost/config/no_tr1/functional.hpp> // for std::less
|
||||
|
||||
#if !defined(BOOST_NO_IOSTREAM)
|
||||
#if !defined(BOOST_NO_IOSFWD)
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
#else
|
||||
#include <ostream>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//
|
||||
// intrusive_ptr
|
||||
//
|
||||
// A smart pointer that uses intrusive reference counting.
|
||||
//
|
||||
// Relies on unqualified calls to
|
||||
//
|
||||
// void intrusive_ptr_add_ref(T * p);
|
||||
// void intrusive_ptr_release(T * p);
|
||||
//
|
||||
// (p != 0)
|
||||
//
|
||||
// The object is responsible for destroying itself.
|
||||
//
|
||||
|
||||
template<class T> class intrusive_ptr
|
||||
{
|
||||
private:
|
||||
|
||||
typedef intrusive_ptr this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
BOOST_CONSTEXPR intrusive_ptr() BOOST_NOEXCEPT : px( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
intrusive_ptr( T * p, bool add_ref = true ): px( p )
|
||||
{
|
||||
if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
template<class U>
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
|
||||
|
||||
#else
|
||||
|
||||
intrusive_ptr( intrusive_ptr<U> const & rhs )
|
||||
|
||||
#endif
|
||||
: px( rhs.get() )
|
||||
{
|
||||
if( px != 0 ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
|
||||
{
|
||||
if( px != 0 ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
|
||||
~intrusive_ptr()
|
||||
{
|
||||
if( px != 0 ) intrusive_ptr_release( px );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Move support
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px )
|
||||
{
|
||||
rhs.px = 0;
|
||||
}
|
||||
|
||||
intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class U> friend class intrusive_ptr;
|
||||
|
||||
template<class U>
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
intrusive_ptr(intrusive_ptr<U> && rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty())
|
||||
|
||||
#else
|
||||
|
||||
intrusive_ptr(intrusive_ptr<U> && rhs)
|
||||
|
||||
#endif
|
||||
: px( rhs.px )
|
||||
{
|
||||
rhs.px = 0;
|
||||
}
|
||||
|
||||
template<class U>
|
||||
intrusive_ptr & operator=(intrusive_ptr<U> && rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< intrusive_ptr<U> && >( rhs ) ).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
intrusive_ptr & operator=(intrusive_ptr const & rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
intrusive_ptr & operator=(T * rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
this_type().swap( *this );
|
||||
}
|
||||
|
||||
void reset( T * rhs )
|
||||
{
|
||||
this_type( rhs ).swap( *this );
|
||||
}
|
||||
|
||||
void reset( T * rhs, bool add_ref )
|
||||
{
|
||||
this_type( rhs, add_ref ).swap( *this );
|
||||
}
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
T * detach() BOOST_NOEXCEPT
|
||||
{
|
||||
T * ret = px;
|
||||
px = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
T & operator*() const
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return *px;
|
||||
}
|
||||
|
||||
T * operator->() const
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return px;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
T * tmp = px;
|
||||
px = rhs.px;
|
||||
rhs.px = tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * px;
|
||||
};
|
||||
|
||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
|
||||
{
|
||||
return a.get() == b;
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
|
||||
{
|
||||
return a.get() != b;
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a != b.get();
|
||||
}
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
|
||||
|
||||
// Resolve the ambiguity between our op!= and the one in rel_ops
|
||||
|
||||
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return std::less<T *>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
// mem_fn support
|
||||
|
||||
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return static_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return const_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return dynamic_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
// operator<<
|
||||
|
||||
#if !defined(BOOST_NO_IOSTREAM)
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
|
||||
|
||||
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// in STLport's no-iostreams mode no iostream symbols can be used
|
||||
#ifndef _STLP_NO_IOSTREAMS
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
|
||||
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
|
||||
using std::basic_ostream;
|
||||
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
|
||||
# else
|
||||
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
|
||||
# endif
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif // _STLP_NO_IOSTREAMS
|
||||
|
||||
#endif // __GNUC__ < 3
|
||||
|
||||
#endif // !defined(BOOST_NO_IOSTREAM)
|
||||
|
||||
// hash_value
|
||||
|
||||
template< class T > struct hash;
|
||||
|
||||
template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
|
||||
{
|
||||
return boost::hash< T* >()( p.get() );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
|
187
include/boost/smart_ptr/intrusive_ref_counter.hpp
Normal file
187
include/boost/smart_ptr/intrusive_ref_counter.hpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2013.
|
||||
* 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 intrusive_ref_counter.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.03.2009
|
||||
*
|
||||
* This header contains a reference counter class for \c intrusive_ptr.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
||||
#define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
// This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter:
|
||||
// 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
|
||||
// Note that there is no inline specifier in the declarations.
|
||||
#pragma warning(disable: 4396)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace sp_adl_block {
|
||||
|
||||
/*!
|
||||
* \brief Thread unsafe reference counter policy for \c intrusive_ref_counter
|
||||
*
|
||||
* The policy instructs the \c intrusive_ref_counter base class to implement
|
||||
* a reference counter suitable for single threaded use only. Pointers to the same
|
||||
* object with this kind of reference counter must not be used by different threads.
|
||||
*/
|
||||
struct thread_unsafe_counter
|
||||
{
|
||||
typedef unsigned int type;
|
||||
|
||||
static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return counter;
|
||||
}
|
||||
|
||||
static void increment(unsigned int& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
|
||||
static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return --counter;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Thread safe reference counter policy for \c intrusive_ref_counter
|
||||
*
|
||||
* The policy instructs the \c intrusive_ref_counter base class to implement
|
||||
* a thread-safe reference counter, if the target platform supports multithreading.
|
||||
*/
|
||||
struct thread_safe_counter
|
||||
{
|
||||
typedef boost::detail::atomic_count type;
|
||||
|
||||
static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< unsigned int >(static_cast< long >(counter));
|
||||
}
|
||||
|
||||
static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
|
||||
static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< unsigned int >(--counter);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
|
||||
class intrusive_ref_counter;
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
|
||||
/*!
|
||||
* \brief A reference counter base class
|
||||
*
|
||||
* This base class can be used with user-defined classes to add support
|
||||
* for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT.
|
||||
* Upon releasing the last \c intrusive_ptr referencing the object
|
||||
* derived from the \c intrusive_ref_counter class, operator \c delete
|
||||
* is automatically called on the pointer to the object.
|
||||
*
|
||||
* The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter.
|
||||
*/
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
class intrusive_ref_counter
|
||||
{
|
||||
private:
|
||||
//! Reference counter type
|
||||
typedef typename CounterPolicyT::type counter_type;
|
||||
//! Reference counter
|
||||
mutable counter_type m_ref_counter;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*
|
||||
* \post <tt>use_count() == 0</tt>
|
||||
*/
|
||||
intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*
|
||||
* \post <tt>use_count() == 0</tt>
|
||||
*/
|
||||
intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Assignment
|
||||
*
|
||||
* \post The reference counter is not modified after assignment
|
||||
*/
|
||||
intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }
|
||||
|
||||
/*!
|
||||
* \return The reference counter
|
||||
*/
|
||||
unsigned int use_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return CounterPolicyT::load(m_ref_counter);
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
|
||||
|
||||
friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
|
||||
{
|
||||
CounterPolicyT::increment(p->m_ref_counter);
|
||||
}
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
|
||||
{
|
||||
if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
|
||||
delete static_cast< const DerivedT* >(p);
|
||||
}
|
||||
|
||||
} // namespace sp_adl_block
|
||||
|
||||
using sp_adl_block::intrusive_ref_counter;
|
||||
using sp_adl_block::thread_unsafe_counter;
|
||||
using sp_adl_block::thread_safe_counter;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
22
include/boost/smart_ptr/make_shared.hpp
Normal file
22
include/boost/smart_ptr/make_shared.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
||||
|
||||
// make_shared.hpp
|
||||
//
|
||||
// Copyright (c) 2007, 2008, 2012 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
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
||||
// for documentation.
|
||||
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE )
|
||||
# include <boost/smart_ptr/make_shared_array.hpp>
|
||||
# include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
158
include/boost/smart_ptr/make_shared_array.hpp
Normal file
158
include/boost/smart_ptr/make_shared_array.hpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_count_impl.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_init(p2, n1);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared() {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(&p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_init(p2, N);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size,
|
||||
const typename boost::detail::array_inner<T>::type& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size
|
||||
};
|
||||
std::size_t n1 = M * size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = reinterpret_cast<T3*>(&value);
|
||||
D1 d1;
|
||||
A1 a1(size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_init<T2, M>(p2, n1, p3);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared(const typename boost::detail::array_inner<T>::type& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size,
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = reinterpret_cast<T3*>(&value);
|
||||
D1 d1;
|
||||
A1 a1(&p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_init<T2, M>(p2, N, p3);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared_noinit(std::size_t size) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_noinit(p2, n1);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared_noinit() {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(&p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_noinit(p2, N);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
1131
include/boost/smart_ptr/make_shared_object.hpp
Normal file
1131
include/boost/smart_ptr/make_shared_object.hpp
Normal file
File diff suppressed because it is too large
Load Diff
105
include/boost/smart_ptr/make_unique.hpp
Normal file
105
include/boost/smart_ptr/make_unique.hpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
(c) 2014-2015 Glen Joseph Fernandes
|
||||
<glenjofe -at- gmail.com>
|
||||
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0.
|
||||
http://boost.org/LICENSE_1_0.txt
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
|
||||
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<class T>
|
||||
struct up_if_object {
|
||||
typedef std::unique_ptr<T> type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_if_object<T[]> { };
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct up_if_object<T[N]> { };
|
||||
|
||||
template<class T>
|
||||
struct up_if_array { };
|
||||
|
||||
template<class T>
|
||||
struct up_if_array<T[]> {
|
||||
typedef std::unique_ptr<T[]> type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_remove_reference {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_remove_reference<T&> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_remove_reference<T&&> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_element { };
|
||||
|
||||
template<class T>
|
||||
struct up_element<T[]> {
|
||||
typedef T type;
|
||||
};
|
||||
} /* detail */
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_object<T>::type make_unique()
|
||||
{
|
||||
return std::unique_ptr<T>(new T());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class T, class... Args>
|
||||
inline typename detail::up_if_object<T>::type
|
||||
make_unique(Args&&... args)
|
||||
{
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_object<T>::type
|
||||
make_unique(typename detail::up_remove_reference<T>::type&& value)
|
||||
{
|
||||
return std::unique_ptr<T>(new T(std::move(value)));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_object<T>::type make_unique_noinit()
|
||||
{
|
||||
return std::unique_ptr<T>(new T);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_array<T>::type make_unique(std::size_t n)
|
||||
{
|
||||
return std::unique_ptr<T>(new
|
||||
typename detail::up_element<T>::type[n]());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_array<T>::type
|
||||
make_unique_noinit(std::size_t n)
|
||||
{
|
||||
return std::unique_ptr<T>(new
|
||||
typename detail::up_element<T>::type[n]);
|
||||
}
|
||||
} /* boost */
|
||||
|
||||
#endif
|
57
include/boost/smart_ptr/owner_less.hpp
Normal file
57
include/boost/smart_ptr/owner_less.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// owner_less.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Frank Mori Hess
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/smart_ptr.htm for documentation.
|
||||
//
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<typename T> class shared_ptr;
|
||||
template<typename T> class weak_ptr;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename T, typename U>
|
||||
struct generic_owner_less : public std::binary_function<T, T, bool>
|
||||
{
|
||||
bool operator()(const T &lhs, const T &rhs) const
|
||||
{
|
||||
return lhs.owner_before(rhs);
|
||||
}
|
||||
bool operator()(const T &lhs, const U &rhs) const
|
||||
{
|
||||
return lhs.owner_before(rhs);
|
||||
}
|
||||
bool operator()(const U &lhs, const T &rhs) const
|
||||
{
|
||||
return lhs.owner_before(rhs);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template<typename T> struct owner_less;
|
||||
|
||||
template<typename T>
|
||||
struct owner_less<shared_ptr<T> >:
|
||||
public detail::generic_owner_less<shared_ptr<T>, weak_ptr<T> >
|
||||
{};
|
||||
|
||||
template<typename T>
|
||||
struct owner_less<weak_ptr<T> >:
|
||||
public detail::generic_owner_less<weak_ptr<T>, shared_ptr<T> >
|
||||
{};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
|
132
include/boost/smart_ptr/scoped_array.hpp
Normal file
132
include/boost/smart_ptr/scoped_array.hpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
|
||||
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 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)
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Debug hooks
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
void sp_array_constructor_hook(void * p);
|
||||
void sp_array_destructor_hook(void * p);
|
||||
|
||||
#endif
|
||||
|
||||
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
|
||||
// is guaranteed, either on destruction of the scoped_array or via an explicit
|
||||
// reset(). Use shared_array or std::vector if your needs are more complex.
|
||||
|
||||
template<class T> class scoped_array // noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
T * px;
|
||||
|
||||
scoped_array(scoped_array const &);
|
||||
scoped_array & operator=(scoped_array const &);
|
||||
|
||||
typedef scoped_array<T> this_type;
|
||||
|
||||
void operator==( scoped_array const& ) const;
|
||||
void operator!=( scoped_array const& ) const;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p )
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_array_constructor_hook( px );
|
||||
#endif
|
||||
}
|
||||
|
||||
~scoped_array() // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_array_destructor_hook( px );
|
||||
#endif
|
||||
boost::checked_array_delete( px );
|
||||
}
|
||||
|
||||
void reset(T * p = 0) // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
{
|
||||
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
||||
this_type(p).swap(*this);
|
||||
}
|
||||
|
||||
T & operator[](std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
BOOST_ASSERT( i >= 0 );
|
||||
return px[i];
|
||||
}
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
void swap(scoped_array & b) BOOST_NOEXCEPT
|
||||
{
|
||||
T * tmp = b.px;
|
||||
b.px = px;
|
||||
px = tmp;
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
|
167
include/boost/smart_ptr/scoped_ptr.hpp
Normal file
167
include/boost/smart_ptr/scoped_ptr.hpp
Normal file
@@ -0,0 +1,167 @@
|
||||
#ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
|
||||
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 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)
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
# include <memory> // for std::auto_ptr
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Debug hooks
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
void sp_scalar_constructor_hook(void * p);
|
||||
void sp_scalar_destructor_hook(void * p);
|
||||
|
||||
#endif
|
||||
|
||||
// scoped_ptr mimics a built-in pointer except that it guarantees deletion
|
||||
// of the object pointed to, either on destruction of the scoped_ptr or via
|
||||
// an explicit reset(). scoped_ptr is a simple solution for simple needs;
|
||||
// use shared_ptr or std::auto_ptr if your needs are more complex.
|
||||
|
||||
template<class T> class scoped_ptr // noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
T * px;
|
||||
|
||||
scoped_ptr(scoped_ptr const &);
|
||||
scoped_ptr & operator=(scoped_ptr const &);
|
||||
|
||||
typedef scoped_ptr<T> this_type;
|
||||
|
||||
void operator==( scoped_ptr const& ) const;
|
||||
void operator!=( scoped_ptr const& ) const;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_ptr( T * p = 0 ): px( p ) // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook( px );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook( px );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
~scoped_ptr() // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_destructor_hook( px );
|
||||
#endif
|
||||
boost::checked_delete( px );
|
||||
}
|
||||
|
||||
void reset(T * p = 0) // never throws
|
||||
{
|
||||
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
||||
this_type(p).swap(*this);
|
||||
}
|
||||
|
||||
T & operator*() const // never throws
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return *px;
|
||||
}
|
||||
|
||||
T * operator->() const // never throws
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return px;
|
||||
}
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
void swap(scoped_ptr & b) BOOST_NOEXCEPT
|
||||
{
|
||||
T * tmp = b.px;
|
||||
b.px = px;
|
||||
px = tmp;
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// get_pointer(p) is a generic way to say p.get()
|
||||
|
||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
|
292
include/boost/smart_ptr/shared_array.hpp
Normal file
292
include/boost/smart_ptr/shared_array.hpp
Normal file
@@ -0,0 +1,292 @@
|
||||
#ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// shared_array.hpp
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002, 2012 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/config.hpp> // for broken compiler workarounds
|
||||
|
||||
#include <memory> // TR1 cyclic inclusion fix
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/shared_count.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <algorithm> // for std::swap
|
||||
#include <functional> // for std::less
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//
|
||||
// shared_array
|
||||
//
|
||||
// shared_array extends shared_ptr to arrays.
|
||||
// The array pointed to is deleted when the last shared_array pointing to it
|
||||
// is destroyed or reset.
|
||||
//
|
||||
|
||||
template<class T> class shared_array
|
||||
{
|
||||
private:
|
||||
|
||||
// Borland 5.5.1 specific workarounds
|
||||
typedef checked_array_deleter<T> deleter;
|
||||
typedef shared_array<T> this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
shared_array() BOOST_NOEXCEPT : px( 0 ), pn()
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
shared_array( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y>
|
||||
explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
//
|
||||
// Requirements: D's copy constructor must not throw
|
||||
//
|
||||
// shared_array will release p by calling d(p)
|
||||
//
|
||||
|
||||
template<class Y, class D> shared_array( Y * p, D d ): px( p ), pn( p, d )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
// As above, but with allocator. A's copy constructor shall not throw.
|
||||
|
||||
template<class Y, class D, class A> shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
// generated copy constructor, destructor are fine...
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
// ... except in C++0x, move disables the implicit copy
|
||||
|
||||
shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||
{
|
||||
}
|
||||
|
||||
shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn()
|
||||
{
|
||||
pn.swap( r.pn );
|
||||
r.px = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// conversion
|
||||
|
||||
template<class Y>
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
shared_array( shared_array<Y> const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() )
|
||||
|
||||
#else
|
||||
|
||||
shared_array( shared_array<Y> const & r )
|
||||
|
||||
#endif
|
||||
BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
// aliasing
|
||||
|
||||
template< class Y >
|
||||
shared_array( shared_array<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
|
||||
{
|
||||
}
|
||||
|
||||
// assignment
|
||||
|
||||
shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( r ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
|
||||
|
||||
template<class Y>
|
||||
shared_array & operator=( shared_array<Y> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( r ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< shared_array && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_array & operator=( shared_array<Y> && r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
this_type().swap( *this );
|
||||
}
|
||||
|
||||
template<class Y> void reset( Y * p ) // Y must be complete
|
||||
{
|
||||
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
||||
this_type( p ).swap( *this );
|
||||
}
|
||||
|
||||
template<class Y, class D> void reset( Y * p, D d )
|
||||
{
|
||||
this_type( p, d ).swap( *this );
|
||||
}
|
||||
|
||||
template<class Y, class D, class A> void reset( Y * p, D d, A a )
|
||||
{
|
||||
this_type( p, d, a ).swap( *this );
|
||||
}
|
||||
|
||||
template<class Y> void reset( shared_array<Y> const & r, element_type * p )
|
||||
{
|
||||
this_type( r, p ).swap( *this );
|
||||
}
|
||||
|
||||
T & operator[] (std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
BOOST_ASSERT(i >= 0);
|
||||
return px[i];
|
||||
}
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
bool unique() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.unique();
|
||||
}
|
||||
|
||||
long use_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.use_count();
|
||||
}
|
||||
|
||||
void swap(shared_array<T> & other) BOOST_NOEXCEPT
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
pn.swap(other.pn);
|
||||
}
|
||||
|
||||
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
|
||||
{
|
||||
return pn.get_deleter( ti );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<class Y> friend class shared_array;
|
||||
|
||||
T * px; // contained pointer
|
||||
detail::shared_count pn; // reference counter
|
||||
|
||||
}; // shared_array
|
||||
|
||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return std::less<T*>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
template< class D, class T > D * get_deleter( shared_array<T> const & p )
|
||||
{
|
||||
return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
|
1094
include/boost/smart_ptr/shared_ptr.hpp
Normal file
1094
include/boost/smart_ptr/shared_ptr.hpp
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user