mirror of
				https://github.com/boostorg/smart_ptr.git
				synced 2025-10-26 13:21:39 +01:00 
			
		
		
		
	Compare commits
	
		
			464 Commits
		
	
	
		
			boost-1.65
			...
			feature/qu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 82e80c7175 | ||
|  | 81318213a6 | ||
|  | 85c2a6ea74 | ||
|  | 9723621128 | ||
|  | 6dffeb8a75 | ||
|  | bee3766c04 | ||
|  | 86a873a58c | ||
|  | c808ca7ac8 | ||
|  | a4e0508ab7 | ||
|  | 1dcc441ca1 | ||
|  | cdf118b15b | ||
|  | ab75e1f892 | ||
|  | dcfb560de3 | ||
|  | 362fb1d677 | ||
|  | 79dac0e691 | ||
|  | d08d035bdf | ||
|  | 709e446968 | ||
|  | 0b0924ff82 | ||
|  | e7433ba545 | ||
|  | 785a17aaaf | ||
|  | 576d31f206 | ||
|  | 1b89a64e9b | ||
|  | 840e2ff1a8 | ||
|  | 622e2c3f83 | ||
|  | 0630607f39 | ||
|  | 316f4cef77 | ||
|  | 9e866b8a95 | ||
|  | cd01b87478 | ||
|  | b3a4c39456 | ||
|  | 5cdd3585db | ||
|  | 916c8a7d7c | ||
|  | beaf20e7b5 | ||
|  | 5e6b3a9702 | ||
|  | 63589908b5 | ||
|  | 9466e73cbe | ||
|  | b12e342c52 | ||
|  | 7f880bc205 | ||
|  | 90fd5a1fc9 | ||
|  | 0bedddbf16 | ||
|  | 173cf9ad7b | ||
|  | 9db2b96843 | ||
|  | 9b309184f8 | ||
|  | 7c87ae7985 | ||
|  | f2abcf1654 | ||
|  | 1361171bac | ||
|  | c5023afe04 | ||
|  | 7cfc326207 | ||
|  | 6b7effc83d | ||
|  | 89b4fa2552 | ||
|  | f991bdc8b3 | ||
|  | f57b455020 | ||
|  | 8b22f5cb4f | ||
|  | 1c988756d5 | ||
|  | 890b661909 | ||
|  | ab13ffa91d | ||
|  | 950ef1c130 | ||
|  | fc43a2b9d1 | ||
|  | df366326e1 | ||
|  | d77c27986e | ||
|  | dbceed6210 | ||
|  | 9ed43780e4 | ||
|  | 9026b9c556 | ||
|  | c4fed8ca7f | ||
|  | f866c6a9ae | ||
|  | 87a4dc144f | ||
|  | e6529af03f | ||
|  | b521582d46 | ||
|  | ca64f5c015 | ||
|  | 9a1d7008eb | ||
|  | 8a03c71a28 | ||
|  | 222323dc49 | ||
|  | 62fd6baa48 | ||
|  | 96ef19e72d | ||
|  | 78057574cf | ||
|  | 03e1bb314b | ||
|  | 505ed6753d | ||
|  | 82bee8581d | ||
|  | b4174f66fa | ||
|  | bf31a25fa5 | ||
|  | 06da5cd574 | ||
|  | c0c6244297 | ||
|  | b0200dd829 | ||
|  | 7f7e3748cf | ||
|  | 682b285a21 | ||
|  | 94d31304f3 | ||
|  | aa1a9ef2d7 | ||
|  | 63ac28d26f | ||
|  | 72a019944c | ||
|  | 12733a052b | ||
|  | e5472d59d1 | ||
|  | d58213cfcb | ||
|  | 38d54034d7 | ||
|  | 8863958e8d | ||
|  | 123040290c | ||
|  | abb0071ca6 | ||
|  | 000c7ae5ac | ||
|  | f11b931cfd | ||
|  | 5d8304d2cc | ||
|  | 044d1f2cb9 | ||
|  | dccecc2500 | ||
|  | 0aa32dc692 | ||
|  | b4a0629b63 | ||
|  | 38b737c490 | ||
|  | 314267a5f7 | ||
|  | ce308f21e8 | ||
|  | cd0b99380e | ||
|  | 0e6dd82e8e | ||
|  | 569b07b91c | ||
|  | bd0419c290 | ||
|  | 26cf7ff744 | ||
|  | c132c339c7 | ||
|  | 4a3432759d | ||
|  | 3832411d31 | ||
|  | 66e6f9b2ef | ||
|  | d2c2407585 | ||
|  | 694e6822ac | ||
|  | fd94706918 | ||
|  | c5e1280b77 | ||
|  | d66b173710 | ||
|  | d908c4d288 | ||
|  | 41a36f89ec | ||
|  | c1e7bd1a51 | ||
|  | 1dddd9f306 | ||
|  | e9c54b2430 | ||
|  | 17e299f11e | ||
|  | 71902a7bdb | ||
|  | e9790f99f7 | ||
|  | d4c605e6ff | ||
|  | f5152b0904 | ||
|  | 7caada352c | ||
|  | 11e56a4ad9 | ||
|  | c33504189a | ||
|  | 960741cb2e | ||
|  | c8ef3e2276 | ||
|  | 72c25383d5 | ||
|  | 6b826f1139 | ||
|  | 591d0e0728 | ||
|  | e86015f9f6 | ||
|  | 4f9487d0f3 | ||
|  | 0925dcce4e | ||
|  | 6bc7ec7e6b | ||
|  | 1650077eee | ||
|  | 635dfe46ee | ||
|  | fc0eeeffa6 | ||
|  | 4df3174d4a | ||
|  | 1a51e0f02c | ||
|  | c4ae5e0c42 | ||
|  | 85b0ab073c | ||
|  | ac9154d1e5 | ||
|  | 788313fda2 | ||
|  | 3ef8cfd02f | ||
|  | cd2aac8442 | ||
|  | 3ca07d82a7 | ||
|  | f8303629f1 | ||
|  | ef0e40bcda | ||
|  | 4af91d46f1 | ||
|  | 42dfdc9e51 | ||
|  | 763c7f56cd | ||
|  | 029f089a4a | ||
|  | 66d11714bd | ||
|  | ac0381f0b8 | ||
|  | 13be03abf8 | ||
|  | 5e7596ef06 | ||
|  | ef1651449f | ||
|  | b34786c4d4 | ||
|  | aacfb25c82 | ||
|  | c7349834be | ||
|  | 414b0a65d9 | ||
|  | bcb2566e74 | ||
|  | 7070f9b3f8 | ||
|  | 78fd14f412 | ||
|  | 861622d329 | ||
|  | 366c60ad3b | ||
|  | 331c50132b | ||
|  | 97c9204a95 | ||
|  | c577d68b02 | ||
|  | 2ce29622f5 | ||
|  | 7e9c54ffa2 | ||
|  | ca8d5216fc | ||
|  | 79e46f1719 | ||
|  | e6b5dc5ada | ||
|  | dd57aa5b70 | ||
|  | e4637b8500 | ||
|  | a0d4ec3915 | ||
|  | 59b5b17e81 | ||
|  | f2ab3b21f0 | ||
|  | e04196b6a1 | ||
|  | 95eaa2d7c3 | ||
|  | 2e31d0d633 | ||
|  | b8cb132ab4 | ||
|  | f4d7116241 | ||
|  | f2cc84a23c | ||
|  | f12a33813d | ||
|  | cfde4f7407 | ||
|  | b8d340b495 | ||
|  | 6716193d9c | ||
|  | 8f40bff2f6 | ||
|  | 1ef8f4e72d | ||
|  | f651a49d96 | ||
|  | 598314b8e1 | ||
|  | 72221d1da0 | ||
|  | 2cbeb5b185 | ||
|  | 67e657c228 | ||
|  | eba3cf92e7 | ||
|  | 8340a13539 | ||
|  | 098d0f4ce3 | ||
|  | fec5fb97c8 | ||
|  | b52d7548b3 | ||
|  | 594c7485a5 | ||
|  | d751041fb9 | ||
|  | d41546ddce | ||
|  | f3424e74e8 | ||
|  | 0eee7efd54 | ||
|  | dc2a127369 | ||
|  | 42575a0e51 | ||
|  | 64b2eac868 | ||
|  | 856ed108e8 | ||
|  | 678a544d27 | ||
|  | f1b06df6f4 | ||
|  | 620620df3d | ||
|  | 0bd61c1089 | ||
|  | d1295a9974 | ||
|  | 6e8c15c02f | ||
|  | 7c0dcd338a | ||
|  | 8d79ceaf8a | ||
|  | d35cf29b99 | ||
|  | 72ca834ae8 | ||
|  | 8afe162910 | ||
|  | 5d31c1c443 | ||
|  | 3db4ad9a15 | ||
|  | d0655ab145 | ||
|  | 7c01e640f7 | ||
|  | 00db1e02c6 | ||
|  | 914b93430a | ||
|  | 15ffd7852b | ||
|  | c66c4f5ed1 | ||
|  | 7e9d8c39a3 | ||
|  | a0d08b17e0 | ||
|  | 108a86cdbd | ||
|  | d08bdc86e5 | ||
|  | f8dcf5f6f4 | ||
|  | d38f64ded9 | ||
|  | b66fe51566 | ||
|  | 1b5568d585 | ||
|  | fad0c20263 | ||
|  | 1c61e54b13 | ||
|  | a0fc1e6daa | ||
|  | 5dd84ea389 | ||
|  | bc677e9098 | ||
|  | 688cfed63e | ||
|  | c63dc266b9 | ||
|  | 6c181a0707 | ||
|  | 4047290b85 | ||
|  | dc6c76d7e9 | ||
|  | 5a18ffdc56 | ||
|  | 09fdd5ebfd | ||
|  | 911874e139 | ||
|  | c7c0eacb74 | ||
|  | 9ed9f43ca8 | ||
|  | 0ddf990869 | ||
|  | a08a5f3d41 | ||
|  | 77c2d4cad7 | ||
|  | fd612dc114 | ||
|  | e67ebef9a7 | ||
|  | 6f5b9c7b37 | ||
|  | 91f3aa0386 | ||
|  | 686a354f21 | ||
|  | efceb04665 | ||
|  | ca57860ae2 | ||
|  | 9dcd05f918 | ||
|  | 4b724ab3f8 | ||
|  | 58915ca2fe | ||
|  | 62b0e5cdf4 | ||
|  | 951ff783b5 | ||
|  | 6421394e70 | ||
|  | 121312cc22 | ||
|  | 1e5df9d551 | ||
|  | 496127ab99 | ||
|  | 2af343a2cb | ||
|  | c6b3700ef1 | ||
|  | 2a93d30e73 | ||
|  | 02cc561248 | ||
|  | 066b398114 | ||
|  | 9c43c69c14 | ||
|  | eb8998cd91 | ||
|  | df06c324a7 | ||
|  | 0ddfab493c | ||
|  | a2732e207a | ||
|  | 5be7523ebe | ||
|  | 2320dafc03 | ||
|  | 7ab4093f46 | ||
|  | 296c203135 | ||
|  | 2dd35e5fbc | ||
|  | 977544feda | ||
|  | 54b5498208 | ||
|  | da81452f1f | ||
|  | 7b9a969215 | ||
|  | cd562eb053 | ||
|  | 91cd83e5bf | ||
|  | 2fdb8c4b0a | ||
|  | e806b53433 | ||
|  | e0c7bd9a7e | ||
|  | 766ab05a12 | ||
|  | 05cbefd28e | ||
|  | bfbdf4f45f | ||
|  | 169c0cd52a | ||
|  | 7d70691a16 | ||
|  | 90c27d7cfa | ||
|  | 43d1fe12c5 | ||
|  | a2749dddb4 | ||
|  | a71e62146c | ||
|  | 274ec17836 | ||
|  | a7341070f1 | ||
|  | a6323354cd | ||
|  | f788448101 | ||
|  | 283f2d2a11 | ||
|  | 034f94617d | ||
|  | 6a5f67b3a2 | ||
|  | dcd3c8ef80 | ||
|  | bb2a453ff6 | ||
|  | e56eec70ca | ||
|  | 60c26acab8 | ||
|  | 00f6b5dcb0 | ||
|  | 6195ae1eb0 | ||
|  | 30291c406a | ||
|  | 610f19f247 | ||
|  | 876d40a9ab | ||
|  | e4d642c46a | ||
|  | 3dffa64f58 | ||
|  | af92bd89ef | ||
|  | 4742143605 | ||
|  | 872bf10347 | ||
|  | c0ae9b3728 | ||
|  | 1298c2e8e5 | ||
|  | d593061b15 | ||
|  | 5072045f12 | ||
|  | 442e179920 | ||
|  | 9544a8cb91 | ||
|  | 5823d6bcc9 | ||
|  | f56e609757 | ||
|  | 8df63a3d0e | ||
|  | 4b6cb1223b | ||
|  | 719e819570 | ||
|  | a571b3a250 | ||
|  | f17c5e8e3b | ||
|  | e306b30dcf | ||
|  | b6b49ef591 | ||
|  | 2122c7753c | ||
|  | 7c76fb385d | ||
|  | 372fac679b | ||
|  | e3adcaed1e | ||
|  | 016e682af6 | ||
|  | 78e095d761 | ||
|  | eb8a91cb46 | ||
|  | 513cd15378 | ||
|  | 7bfa6a1f3d | ||
|  | 8120bb44cb | ||
|  | 18974ea2db | ||
|  | 2a4aca403a | ||
|  | 4d0d81477c | ||
|  | 1725e26f70 | ||
|  | 47fffaf11c | ||
|  | 7f0323a347 | ||
|  | 6d8ea0f0c4 | ||
|  | d10299159a | ||
|  | adcab0e313 | ||
|  | 4fbb9ff076 | ||
|  | 8ccb36dfcf | ||
|  | fde2e91443 | ||
|  | aa1341a6a2 | ||
|  | 053779f3ee | ||
|  | 51d8167fbf | ||
|  | 5f95fe9848 | ||
|  | 599d0bbba9 | ||
|  | f769217ca8 | ||
|  | 5d5d28a92e | ||
|  | 85fd341402 | ||
|  | eac6411867 | ||
|  | 97ef7970e8 | ||
|  | 4baa21dd5e | ||
|  | d0a89a81f0 | ||
|  | ab2b977e4a | ||
|  | f380d4466c | ||
|  | 2932ca4203 | ||
|  | 660d26c2c3 | ||
|  | a095084492 | ||
|  | a314765b94 | ||
|  | 02eba55685 | ||
|  | 9c2c991291 | ||
|  | 2e57ddb953 | ||
|  | f6c3508aee | ||
|  | b7cca00408 | ||
|  | 7e50abb9ec | ||
|  | e7360779b0 | ||
|  | 456da93897 | ||
|  | 04f0847af4 | ||
|  | 29a08cdff6 | ||
|  | 6d3af760f6 | ||
|  | a9f39d2b94 | ||
|  | 4e2f236116 | ||
|  | 4eb53db537 | ||
|  | a2b6ba85f3 | ||
|  | e37cd4154f | ||
|  | 8563fc5c4e | ||
|  | 67fab5c9ec | ||
|  | f16fbdce26 | ||
|  | c3b3835a58 | ||
|  | d1600b8abc | ||
|  | 5885763287 | ||
|  | 9bb12692b3 | ||
|  | 773ef80f5d | ||
|  | 704de2bd67 | ||
|  | 1caa233faa | ||
|  | 605d4a2789 | ||
|  | 6ab9b93088 | ||
|  | 4129bb6a5c | ||
|  | 3b64e5ecb3 | ||
|  | 4025698fe8 | ||
|  | 2d7ab197a7 | ||
|  | 5877b08490 | ||
|  | ffe5b46f75 | ||
|  | 4abc74fe28 | ||
|  | 12a646c607 | ||
|  | 937a3e0e93 | ||
|  | 258fa75a7e | ||
|  | 93d0d69f5e | ||
|  | f173f9c0fb | ||
|  | 6a5942f55f | ||
|  | 293a4ee009 | ||
|  | 8e3aa3a565 | ||
|  | 78bebd5166 | ||
|  | a47cf35b0f | ||
|  | 8d0afb670f | ||
|  | 77a35856c6 | ||
|  | 693109361e | ||
|  | 6735806863 | ||
|  | b0dc300154 | ||
|  | adc998469a | ||
|  | 4252ed31de | ||
|  | 279372a784 | ||
|  | b77b7cfd62 | ||
|  | 2553a71b79 | ||
|  | 5dfcd2a6e4 | ||
|  | 6f30b395e4 | ||
|  | 014318a1ba | ||
|  | d2c8eea08d | ||
|  | 4e0d47302b | ||
|  | 765840cd71 | ||
|  | cb4a878fa8 | ||
|  | 57a585ed46 | ||
|  | 949338ff18 | ||
|  | 50fbbe91d8 | ||
|  | e88227b506 | ||
|  | 410f2ce8d4 | ||
|  | 4e2e758f58 | ||
|  | 9cb8ee086f | ||
|  | a054a570c1 | ||
|  | 219dc523ec | ||
|  | 5da882293d | ||
|  | 868a870a59 | ||
|  | 10c6233029 | ||
|  | bcfe1be681 | ||
|  | 966786e7f9 | ||
|  | 087471a232 | 
							
								
								
									
										421
									
								
								.drone.jsonnet
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										421
									
								
								.drone.jsonnet
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,421 @@ | ||||
| # Copyright 2022 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| local library = "smart_ptr"; | ||||
|  | ||||
| local triggers = | ||||
| { | ||||
|     branch: [ "master", "develop", "feature/*" ] | ||||
| }; | ||||
|  | ||||
| local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' }; | ||||
| local asan = { ASAN: '1' }; | ||||
|  | ||||
| local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") = | ||||
| { | ||||
|     name: name, | ||||
|     kind: "pipeline", | ||||
|     type: "docker", | ||||
|     trigger: triggers, | ||||
|     platform: | ||||
|     { | ||||
|         os: "linux", | ||||
|         arch: arch | ||||
|     }, | ||||
|     steps: | ||||
|     [ | ||||
|         { | ||||
|             name: "everything", | ||||
|             image: image, | ||||
|             environment: environment, | ||||
|             commands: | ||||
|             [ | ||||
|                 'set -e', | ||||
|                 'uname -a', | ||||
|                 'echo $DRONE_STAGE_MACHINE', | ||||
|             ] + | ||||
|             (if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) + | ||||
|             (if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) + | ||||
|             [ | ||||
|                 'export LIBRARY=' + library, | ||||
|                 './.drone/drone.sh', | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
| }; | ||||
|  | ||||
| local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") = | ||||
| { | ||||
|     name: name, | ||||
|     kind: "pipeline", | ||||
|     type: "exec", | ||||
|     trigger: triggers, | ||||
|     platform: { | ||||
|         "os": "darwin", | ||||
|         "arch": arch | ||||
|     }, | ||||
|     node: { | ||||
|         "os": osx_version | ||||
|     }, | ||||
|     steps: [ | ||||
|         { | ||||
|             name: "everything", | ||||
|             environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" }, | ||||
|             commands: | ||||
|             [ | ||||
|                 'export LIBRARY=' + library, | ||||
|                 './.drone/drone.sh', | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
| }; | ||||
|  | ||||
| local windows_pipeline(name, image, environment, arch = "amd64") = | ||||
| { | ||||
|     name: name, | ||||
|     kind: "pipeline", | ||||
|     type: "docker", | ||||
|     trigger: triggers, | ||||
|     platform: | ||||
|     { | ||||
|         os: "windows", | ||||
|         arch: arch | ||||
|     }, | ||||
|     "steps": | ||||
|     [ | ||||
|         { | ||||
|             name: "everything", | ||||
|             image: image, | ||||
|             environment: environment, | ||||
|             commands: | ||||
|             [ | ||||
|                 'cmd /C .drone\\\\drone.bat ' + library, | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
| }; | ||||
|  | ||||
| [ | ||||
|     linux_pipeline( | ||||
|         "Linux 14.04 GCC 4.8*", | ||||
|         "cppalliance/droneubuntu1404:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11' }, | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 14.04 GCC 4.9", | ||||
|         "cppalliance/droneubuntu1404:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11' }, | ||||
|         "g++-4.9", | ||||
|         [ "ppa:ubuntu-toolchain-r/test" ], | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 16.04 GCC 5*", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14' }, | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 18.04 GCC 6", | ||||
|         "cppalliance/droneubuntu1804:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '11,14' }, | ||||
|         "g++-6", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 18.04 GCC 7* 32/64", | ||||
|         "cppalliance/droneubuntu1804:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17', ADDRMD: '32,64' }, | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 18.04 GCC 8 32/64", | ||||
|         "cppalliance/droneubuntu1804:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '11,14,17', ADDRMD: '32,64' }, | ||||
|         "g++-8-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 GCC 9* 32/64", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' }, | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 GCC 9* ARM64", | ||||
|         "cppalliance/droneubuntu2004:multiarch", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' }, | ||||
|         arch="arm64", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 GCC 9* S390x", | ||||
|         "cppalliance/droneubuntu2004:multiarch", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' }, | ||||
|         arch="s390x", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 GCC 10 32/64", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14,17,20', ADDRMD: '32,64' }, | ||||
|         "g++-10-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 22.04 GCC 11* 32/64", | ||||
|         "cppalliance/droneubuntu2204:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' }, | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 22.04 GCC 12 32/64", | ||||
|         "cppalliance/droneubuntu2204:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' }, | ||||
|         "g++-12-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 GCC 13 32 ASAN", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + asan, | ||||
|         "g++-13-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 GCC 13 32 UBSAN", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + ubsan, | ||||
|         "g++-13-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 GCC 13 64 UBSAN", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + ubsan, | ||||
|         "g++-13-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 GCC 14 UBSAN", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b' } + ubsan, | ||||
|         "g++-14-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 GCC 14 ASAN", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b' } + asan, | ||||
|         "g++-14-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 16.04 Clang 3.5", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '11' }, | ||||
|         "clang-3.5", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 16.04 Clang 3.6", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '11,14' }, | ||||
|         "clang-3.6", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 16.04 Clang 3.7", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '11,14' }, | ||||
|         "clang-3.7", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 16.04 Clang 3.8", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '11,14' }, | ||||
|         "clang-3.8", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 18.04 Clang 3.9", | ||||
|         "cppalliance/droneubuntu1804:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-3.9', CXXSTD: '11,14' }, | ||||
|         "clang-3.9", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 18.04 Clang 4.0", | ||||
|         "cppalliance/droneubuntu1804:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-4.0', CXXSTD: '11,14' }, | ||||
|         "clang-4.0", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 18.04 Clang 5.0", | ||||
|         "cppalliance/droneubuntu1804:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '11,14' }, | ||||
|         "clang-5.0", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 Clang 6.0", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-6.0', CXXSTD: '11,14,17' }, | ||||
|         "clang-6.0", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 Clang 7", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '11,14,17' }, | ||||
|         "clang-7", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 Clang 8", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '11,14,17' }, | ||||
|         "clang-8", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 Clang 9", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '11,14,17,2a' }, | ||||
|         "clang-9", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 Clang 10", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '11,14,17,2a' }, | ||||
|         "clang-10", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 Clang 11", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '11,14,17,2a' }, | ||||
|         "clang-11", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 20.04 Clang 12", | ||||
|         "cppalliance/droneubuntu2004:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '11,14,17,20' }, | ||||
|         "clang-12", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 22.04 Clang 13", | ||||
|         "cppalliance/droneubuntu2204:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '11,14,17,20,2b' }, | ||||
|         "clang-13", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 22.04 Clang 14", | ||||
|         "cppalliance/droneubuntu2204:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14,17,20,2b' }, | ||||
|         "clang-14", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 22.04 Clang 15", | ||||
|         "cppalliance/droneubuntu2204:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '11,14,17,20,2b' }, | ||||
|         "clang-15", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 Clang 16", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '11,14,17,20,2b' }, | ||||
|         "clang-16", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 Clang 17", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' }, | ||||
|         "clang-17", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 Clang 18", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' }, | ||||
|         "clang-18", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 Clang 19", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-19', CXXSTD: '11,14,17,20,2b' }, | ||||
|         "clang-19", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 Clang 20 UBSAN", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '11,14,17,20,23,2c' } + ubsan, | ||||
|         "clang-20", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 24.04 Clang 20 ASAN", | ||||
|         "cppalliance/droneubuntu2404:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '11,14,17,20,23,2c' } + asan, | ||||
|         "clang-20", | ||||
|     ), | ||||
|  | ||||
|     macos_pipeline( | ||||
|         "MacOS 10.15 Xcode 12.2 UBSAN", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan, | ||||
|     ), | ||||
|  | ||||
|     macos_pipeline( | ||||
|         "MacOS 10.15 Xcode 12.2 ASAN", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + asan, | ||||
|     ), | ||||
|  | ||||
|     macos_pipeline( | ||||
|         "MacOS 12.4 Xcode 13.4.1 UBSAN", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + ubsan, | ||||
|         xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64", | ||||
|     ), | ||||
|  | ||||
|     macos_pipeline( | ||||
|         "MacOS 12.4 Xcode 13.4.1 ASAN", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + asan, | ||||
|         xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64", | ||||
|     ), | ||||
|  | ||||
|     windows_pipeline( | ||||
|         "Windows VS2015 msvc-14.0", | ||||
|         "cppalliance/dronevs2015", | ||||
|         { TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', B2_DONT_EMBED_MANIFEST: '1' }, | ||||
|     ), | ||||
|  | ||||
|     windows_pipeline( | ||||
|         "Windows VS2017 msvc-14.1", | ||||
|         "cppalliance/dronevs2017", | ||||
|         { TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' }, | ||||
|     ), | ||||
|  | ||||
|     windows_pipeline( | ||||
|         "Windows VS2019 msvc-14.2", | ||||
|         "cppalliance/dronevs2019", | ||||
|         { TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' }, | ||||
|     ), | ||||
|  | ||||
|     windows_pipeline( | ||||
|         "Windows VS2022 msvc-14.3", | ||||
|         "cppalliance/dronevs2022:1", | ||||
|         { TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' }, | ||||
|     ), | ||||
| ] | ||||
							
								
								
									
										23
									
								
								.drone/drone.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								.drone/drone.bat
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| @REM Copyright 2022 Peter Dimov | ||||
| @REM Distributed under the Boost Software License, Version 1.0. | ||||
| @REM https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| @ECHO ON | ||||
|  | ||||
| set LIBRARY=%1 | ||||
| set DRONE_BUILD_DIR=%CD% | ||||
|  | ||||
| set BOOST_BRANCH=develop | ||||
| if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master | ||||
| cd .. | ||||
| git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
| cd boost-root | ||||
| git submodule update --init tools/boostdep | ||||
| xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\ | ||||
| python tools/boostdep/depinst/depinst.py %LIBRARY% | ||||
| cmd /c bootstrap | ||||
| b2 -d0 headers | ||||
|  | ||||
| if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% | ||||
| if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD% | ||||
| b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker | ||||
							
								
								
									
										25
									
								
								.drone/drone.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										25
									
								
								.drone/drone.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Copyright 2022 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| set -ex | ||||
| export PATH=~/.local/bin:/usr/local/bin:$PATH | ||||
|  | ||||
| DRONE_BUILD_DIR=$(pwd) | ||||
|  | ||||
| BOOST_BRANCH=develop | ||||
| if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi | ||||
|  | ||||
| cd .. | ||||
| git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
| cd boost-root | ||||
| git submodule update --init tools/boostdep | ||||
| cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY | ||||
| python tools/boostdep/depinst/depinst.py $LIBRARY | ||||
| ./bootstrap.sh | ||||
| ./b2 -d0 headers | ||||
|  | ||||
| echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam | ||||
| ./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} | ||||
							
								
								
									
										662
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										662
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,662 @@ | ||||
| name: CI | ||||
|  | ||||
| on: | ||||
|   pull_request: | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
|       - develop | ||||
|       - feature/** | ||||
|  | ||||
| env: | ||||
|   UBSAN_OPTIONS: print_stacktrace=1 | ||||
|  | ||||
| jobs: | ||||
|   posix: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - toolset: gcc-4.8 | ||||
|             cxxstd: "11" | ||||
|             container: ubuntu:18.04 | ||||
|             os: ubuntu-latest | ||||
|             install: g++-4.8-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-5 | ||||
|             cxxstd: "11,14,1z" | ||||
|             container: ubuntu:18.04 | ||||
|             os: ubuntu-latest | ||||
|             install: g++-5-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-6 | ||||
|             cxxstd: "11,14,1z" | ||||
|             container: ubuntu:18.04 | ||||
|             os: ubuntu-latest | ||||
|             install: g++-6-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-7 | ||||
|             cxxstd: "11,14,17" | ||||
|             container: ubuntu:18.04 | ||||
|             os: ubuntu-latest | ||||
|             install: g++-7-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-8 | ||||
|             cxxstd: "11,14,17,2a" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: g++-8-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-9 | ||||
|             cxxstd: "11,14,17,2a" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: g++-9-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-10 | ||||
|             cxxstd: "11,14,17,2a" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: g++-10-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-11 | ||||
|             cxxstd: "11,14,17,20" | ||||
|             os: ubuntu-22.04 | ||||
|             install: g++-11-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-12 | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             os: ubuntu-22.04 | ||||
|             install: g++-12-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-13 | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:24.04 | ||||
|             install: g++-13-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-14 | ||||
|             cxxstd: "11,14,17,20,23,2c" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:24.04 | ||||
|             install: g++-14-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: gcc-15 | ||||
|             cxxstd: "11,14,17,20,23,2c" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:25.04 | ||||
|             install: g++-15-multilib | ||||
|             address-model: 32,64 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-3.9 | ||||
|             cxxstd: "11,14" | ||||
|             container: ubuntu:18.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-3.9 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-4.0 | ||||
|             cxxstd: "11,14" | ||||
|             container: ubuntu:18.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-4.0 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-5.0 | ||||
|             cxxstd: "11,14,1z" | ||||
|             container: ubuntu:18.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-5.0 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-6.0 | ||||
|             cxxstd: "11,14,17" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-6.0 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-7 | ||||
|             cxxstd: "11,14,17" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-7 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-8 | ||||
|             cxxstd: "11,14,17" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-8 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-9 | ||||
|             cxxstd: "11,14,17,2a" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-9 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-10 | ||||
|             cxxstd: "11,14,17,2a" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-10 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-11 | ||||
|             cxxstd: "11,14,17,2a" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-11 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-12 | ||||
|             cxxstd: "11,14,17,20" | ||||
|             container: ubuntu:20.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-12 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-13 | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             container: ubuntu:22.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-13 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-14 | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             container: ubuntu:22.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-14 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-15 | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             container: ubuntu:22.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-15 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-16 | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             container: ubuntu:24.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-16 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-17 | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             container: ubuntu:24.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-17 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-18 | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             container: ubuntu:24.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-18 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-19 | ||||
|             cxxstd: "11,14,17,20,23,2c" | ||||
|             container: ubuntu:24.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-19 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-20 | ||||
|             cxxstd: "11,14,17,20,23,2c" | ||||
|             container: ubuntu:25.04 | ||||
|             os: ubuntu-latest | ||||
|             install: clang-20 | ||||
|           - toolset: clang | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             os: macos-13 | ||||
|           - toolset: clang | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             os: macos-14 | ||||
|           - toolset: clang | ||||
|             cxxstd: "11,14,17,20,2b" | ||||
|             os: macos-15 | ||||
|  | ||||
|     runs-on: ${{matrix.os}} | ||||
|  | ||||
|     container: | ||||
|       image: ${{matrix.container}} | ||||
|       volumes: | ||||
|         - /node20217:/node20217:rw,rshared | ||||
|         - ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }} | ||||
|  | ||||
|     defaults: | ||||
|       run: | ||||
|         shell: bash | ||||
|  | ||||
|     steps: | ||||
|       - name: Setup container environment | ||||
|         if: matrix.container | ||||
|         run: | | ||||
|           apt-get update | ||||
|           apt-get -y install sudo python3 git g++ curl xz-utils | ||||
|  | ||||
|       - name: Install nodejs20glibc2.17 | ||||
|         if: ${{ startsWith( matrix.container, 'ubuntu:1' ) }} | ||||
|         run: | | ||||
|           curl -LO https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz | ||||
|           tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217 | ||||
|           ldd /__e/node20/bin/node | ||||
|  | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install packages | ||||
|         if: matrix.install | ||||
|         run: | | ||||
|           sudo apt-get update | ||||
|           sudo apt-get -y install ${{matrix.install}} | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         run: | | ||||
|           echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY | ||||
|           LIBRARY=${GITHUB_REPOSITORY#*/} | ||||
|           echo LIBRARY: $LIBRARY | ||||
|           echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV | ||||
|           echo GITHUB_BASE_REF: $GITHUB_BASE_REF | ||||
|           echo GITHUB_REF: $GITHUB_REF | ||||
|           REF=${GITHUB_BASE_REF:-$GITHUB_REF} | ||||
|           REF=${REF#refs/heads/} | ||||
|           echo REF: $REF | ||||
|           BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true | ||||
|           echo BOOST_BRANCH: $BOOST_BRANCH | ||||
|           cd .. | ||||
|           git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|           cd boost-root | ||||
|           cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY | ||||
|           git submodule update --init tools/boostdep | ||||
|           python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY | ||||
|           ./bootstrap.sh | ||||
|           ./b2 -d0 headers | ||||
|  | ||||
|       - name: Create user-config.jam | ||||
|         if: matrix.compiler | ||||
|         run: | | ||||
|           echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam | ||||
|  | ||||
|       - name: Run tests | ||||
|         run: | | ||||
|           cd ../boost-root | ||||
|           ./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release | ||||
|  | ||||
|   windows: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - toolset: msvc-14.3 | ||||
|             cxxstd: "14,17,20,latest" | ||||
|             addrmd: 32,64 | ||||
|             os: windows-2022 | ||||
|           - toolset: clang-win | ||||
|             cxxstd: "14,17,20,latest" | ||||
|             addrmd: 32,64 | ||||
|             os: windows-2022 | ||||
|           - toolset: gcc | ||||
|             cxxstd: "11,14,17,2a" | ||||
|             addrmd: 64 | ||||
|             os: windows-2022 | ||||
|  | ||||
|     runs-on: ${{matrix.os}} | ||||
|  | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY% | ||||
|           for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi | ||||
|           echo LIBRARY: %LIBRARY% | ||||
|           echo LIBRARY=%LIBRARY%>>%GITHUB_ENV% | ||||
|           echo GITHUB_BASE_REF: %GITHUB_BASE_REF% | ||||
|           echo GITHUB_REF: %GITHUB_REF% | ||||
|           if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% | ||||
|           set BOOST_BRANCH=develop | ||||
|           for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master | ||||
|           echo BOOST_BRANCH: %BOOST_BRANCH% | ||||
|           cd .. | ||||
|           git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|           cd boost-root | ||||
|           xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ | ||||
|           git submodule update --init tools/boostdep | ||||
|           python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% | ||||
|           cmd /c bootstrap | ||||
|           b2 -d0 headers | ||||
|  | ||||
|       - name: Run tests | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root | ||||
|           b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker | ||||
|  | ||||
|   posix-cmake-subdir: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - os: ubuntu-22.04 | ||||
|           - os: ubuntu-24.04 | ||||
|           - os: macos-13 | ||||
|           - os: macos-14 | ||||
|           - os: macos-15 | ||||
|  | ||||
|     runs-on: ${{matrix.os}} | ||||
|  | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install packages | ||||
|         if: matrix.install | ||||
|         run: sudo apt-get -y install ${{matrix.install}} | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         run: | | ||||
|           echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY | ||||
|           LIBRARY=${GITHUB_REPOSITORY#*/} | ||||
|           echo LIBRARY: $LIBRARY | ||||
|           echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV | ||||
|           echo GITHUB_BASE_REF: $GITHUB_BASE_REF | ||||
|           echo GITHUB_REF: $GITHUB_REF | ||||
|           REF=${GITHUB_BASE_REF:-$GITHUB_REF} | ||||
|           REF=${REF#refs/heads/} | ||||
|           echo REF: $REF | ||||
|           BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true | ||||
|           echo BOOST_BRANCH: $BOOST_BRANCH | ||||
|           cd .. | ||||
|           git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|           cd boost-root | ||||
|           cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY | ||||
|           git submodule update --init tools/boostdep | ||||
|           python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY | ||||
|  | ||||
|       - name: Use library with add_subdirectory | ||||
|         run: | | ||||
|           cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test | ||||
|           mkdir __build__ && cd __build__ | ||||
|           cmake .. | ||||
|           cmake --build . | ||||
|           ctest --output-on-failure --no-tests=error | ||||
|  | ||||
|   posix-cmake-install: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - os: ubuntu-22.04 | ||||
|           - os: ubuntu-24.04 | ||||
|           - os: macos-13 | ||||
|           - os: macos-14 | ||||
|           - os: macos-15 | ||||
|  | ||||
|     runs-on: ${{matrix.os}} | ||||
|  | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install packages | ||||
|         if: matrix.install | ||||
|         run: sudo apt-get -y install ${{matrix.install}} | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         run: | | ||||
|           echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY | ||||
|           LIBRARY=${GITHUB_REPOSITORY#*/} | ||||
|           echo LIBRARY: $LIBRARY | ||||
|           echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV | ||||
|           echo GITHUB_BASE_REF: $GITHUB_BASE_REF | ||||
|           echo GITHUB_REF: $GITHUB_REF | ||||
|           REF=${GITHUB_BASE_REF:-$GITHUB_REF} | ||||
|           REF=${REF#refs/heads/} | ||||
|           echo REF: $REF | ||||
|           BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true | ||||
|           echo BOOST_BRANCH: $BOOST_BRANCH | ||||
|           cd .. | ||||
|           git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|           cd boost-root | ||||
|           cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY | ||||
|           git submodule update --init tools/boostdep | ||||
|           python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY | ||||
|  | ||||
|       - name: Configure | ||||
|         run: | | ||||
|           cd ../boost-root | ||||
|           mkdir __build__ && cd __build__ | ||||
|           cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local .. | ||||
|  | ||||
|       - name: Install | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           cmake --build . --target install | ||||
|  | ||||
|       - name: Use the installed library | ||||
|         run: | | ||||
|           cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__ | ||||
|           cmake -DCMAKE_INSTALL_PREFIX=~/.local .. | ||||
|           cmake --build . | ||||
|           ctest --output-on-failure --no-tests=error | ||||
|  | ||||
|   posix-cmake-test: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - os: ubuntu-22.04 | ||||
|           - os: ubuntu-24.04 | ||||
|           - os: macos-13 | ||||
|           - os: macos-14 | ||||
|           - os: macos-15 | ||||
|  | ||||
|     runs-on: ${{matrix.os}} | ||||
|  | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install packages | ||||
|         if: matrix.install | ||||
|         run: sudo apt-get -y install ${{matrix.install}} | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         run: | | ||||
|           echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY | ||||
|           LIBRARY=${GITHUB_REPOSITORY#*/} | ||||
|           echo LIBRARY: $LIBRARY | ||||
|           echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV | ||||
|           echo GITHUB_BASE_REF: $GITHUB_BASE_REF | ||||
|           echo GITHUB_REF: $GITHUB_REF | ||||
|           REF=${GITHUB_BASE_REF:-$GITHUB_REF} | ||||
|           REF=${REF#refs/heads/} | ||||
|           echo REF: $REF | ||||
|           BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true | ||||
|           echo BOOST_BRANCH: $BOOST_BRANCH | ||||
|           cd .. | ||||
|           git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|           cd boost-root | ||||
|           cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY | ||||
|           git submodule update --init tools/boostdep | ||||
|           python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY | ||||
|  | ||||
|       - name: Configure | ||||
|         run: | | ||||
|           cd ../boost-root | ||||
|           mkdir __build__ && cd __build__ | ||||
|           cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON .. | ||||
|  | ||||
|       - name: Build tests | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           cmake --build . --target tests | ||||
|  | ||||
|       - name: Run tests | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           ctest --output-on-failure --no-tests=error | ||||
|  | ||||
|   windows-cmake-subdir: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - os: windows-latest | ||||
|  | ||||
|     runs-on: ${{matrix.os}} | ||||
|  | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY% | ||||
|           for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi | ||||
|           echo LIBRARY: %LIBRARY% | ||||
|           echo LIBRARY=%LIBRARY%>>%GITHUB_ENV% | ||||
|           echo GITHUB_BASE_REF: %GITHUB_BASE_REF% | ||||
|           echo GITHUB_REF: %GITHUB_REF% | ||||
|           if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% | ||||
|           set BOOST_BRANCH=develop | ||||
|           for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master | ||||
|           echo BOOST_BRANCH: %BOOST_BRANCH% | ||||
|           cd .. | ||||
|           git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|           cd boost-root | ||||
|           xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ | ||||
|           git submodule update --init tools/boostdep | ||||
|           python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% | ||||
|  | ||||
|       - name: Use library with add_subdirectory (Debug) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test | ||||
|           mkdir __build__ && cd __build__ | ||||
|           cmake .. | ||||
|           cmake --build . --config Debug | ||||
|           ctest --output-on-failure --no-tests=error -C Debug | ||||
|  | ||||
|       - name: Use library with add_subdirectory (Release) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test/__build__ | ||||
|           cmake --build . --config Release | ||||
|           ctest --output-on-failure --no-tests=error -C Release | ||||
|  | ||||
|   windows-cmake-install: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - os: windows-latest | ||||
|  | ||||
|     runs-on: ${{matrix.os}} | ||||
|  | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY% | ||||
|           for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi | ||||
|           echo LIBRARY: %LIBRARY% | ||||
|           echo LIBRARY=%LIBRARY%>>%GITHUB_ENV% | ||||
|           echo GITHUB_BASE_REF: %GITHUB_BASE_REF% | ||||
|           echo GITHUB_REF: %GITHUB_REF% | ||||
|           if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% | ||||
|           set BOOST_BRANCH=develop | ||||
|           for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master | ||||
|           echo BOOST_BRANCH: %BOOST_BRANCH% | ||||
|           cd .. | ||||
|           git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|           cd boost-root | ||||
|           xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ | ||||
|           git submodule update --init tools/boostdep | ||||
|           python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% | ||||
|  | ||||
|       - name: Configure | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root | ||||
|           mkdir __build__ && cd __build__ | ||||
|           cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix .. | ||||
|  | ||||
|       - name: Install (Debug) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           cmake --build . --target install --config Debug | ||||
|  | ||||
|       - name: Install (Release) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           cmake --build . --target install --config Release | ||||
|  | ||||
|       - name: Use the installed library (Debug) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test && mkdir __build__ && cd __build__ | ||||
|           cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix .. | ||||
|           cmake --build . --config Debug | ||||
|           ctest --output-on-failure --no-tests=error -C Debug | ||||
|  | ||||
|       - name: Use the installed library (Release) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test/__build__ | ||||
|           cmake --build . --config Release | ||||
|           ctest --output-on-failure --no-tests=error -C Release | ||||
|  | ||||
|   windows-cmake-test: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - os: windows-latest | ||||
|  | ||||
|     runs-on: ${{matrix.os}} | ||||
|  | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY% | ||||
|           for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi | ||||
|           echo LIBRARY: %LIBRARY% | ||||
|           echo LIBRARY=%LIBRARY%>>%GITHUB_ENV% | ||||
|           echo GITHUB_BASE_REF: %GITHUB_BASE_REF% | ||||
|           echo GITHUB_REF: %GITHUB_REF% | ||||
|           if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% | ||||
|           set BOOST_BRANCH=develop | ||||
|           for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master | ||||
|           echo BOOST_BRANCH: %BOOST_BRANCH% | ||||
|           cd .. | ||||
|           git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|           cd boost-root | ||||
|           xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ | ||||
|           git submodule update --init tools/boostdep | ||||
|           python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% | ||||
|  | ||||
|       - name: Configure | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root | ||||
|           mkdir __build__ && cd __build__ | ||||
|           cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DBUILD_TESTING=ON .. | ||||
|  | ||||
|       - name: Build tests (Debug) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           cmake --build . --target tests --config Debug | ||||
|  | ||||
|       - name: Run tests (Debug) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           ctest --output-on-failure --no-tests=error -C Debug | ||||
|  | ||||
|       - name: Build tests (Release) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           cmake --build . --target tests --config Release | ||||
|  | ||||
|       - name: Run tests (Release) | ||||
|         shell: cmd | ||||
|         run: | | ||||
|           cd ../boost-root/__build__ | ||||
|           ctest --output-on-failure --no-tests=error -C Release | ||||
							
								
								
									
										540
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										540
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,14 +1,10 @@ | ||||
| # Copyright 2016, 2017 Peter Dimov | ||||
| # Copyright 2016-2020 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| language: cpp | ||||
|  | ||||
| sudo: false | ||||
|  | ||||
| os: | ||||
|   - linux | ||||
|   - osx | ||||
| dist: xenial | ||||
|  | ||||
| branches: | ||||
|   only: | ||||
| @@ -27,480 +23,166 @@ matrix: | ||||
|  | ||||
|   include: | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++03 | ||||
|       env: TOOLSET=gcc CXXSTD=03,11 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.7 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++03 | ||||
|       dist: xenial | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc CXXSTD=03,11,14 | ||||
|  | ||||
|     - os: linux | ||||
|       dist: bionic | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc CXXSTD=03,11,14,17 | ||||
|  | ||||
|     - os: linux | ||||
|       dist: focal | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc CXXSTD=03,11,14,17 | ||||
|  | ||||
|     - os: linux | ||||
|       arch: arm64 | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc CXXSTD=03,11,14 | ||||
|  | ||||
|     - os: linux | ||||
|       arch: ppc64le | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc CXXSTD=03,11,14 | ||||
|  | ||||
|     - os: linux | ||||
|       arch: s390x | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc CXXSTD=03,11,14 | ||||
|  | ||||
|     - os: freebsd | ||||
|       compiler: clang++ | ||||
|       env: TOOLSET=clang CXXSTD=03,11,14,17,2a | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.4 | ||||
|       env: TOOLSET=gcc CXXSTD=98,0x | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.7 | ||||
|             - g++-4.4 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.7 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++11 | ||||
|       compiler: g++-4.6 | ||||
|       env: TOOLSET=gcc CXXSTD=03,0x | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.7 | ||||
|             - g++-4.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.8 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++03 | ||||
|       dist: bionic | ||||
|       compiler: g++-10 | ||||
|       env: UBSAN=1 TOOLSET=gcc CXXSTD=03,11,14 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.8 | ||||
|             - g++-10 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.8 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++11 | ||||
|       dist: bionic | ||||
|       compiler: g++-10 | ||||
|       env: UBSAN=1 TOOLSET=gcc CXXSTD=17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.9 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.9 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-5 | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-5 | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-5 | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-5 | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-6 | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-6 | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-6 | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-6 | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|             - g++-10 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: g++-7 | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++03 | ||||
|       compiler: /usr/bin/clang++ | ||||
|       env: TOOLSET=clang COMMENT=clang-3.3 CXXSTD=03,11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - clang-3.3 | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: g++-7 | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++11 | ||||
|       compiler: /usr/bin/clang++ | ||||
|       env: TOOLSET=clang COMMENT=clang-3.4 CXXSTD=03,11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|             - clang-3.4 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-11 | ||||
|       env: UBSAN=1 TOOLSET=clang CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-11 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-11 main' | ||||
|               key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: g++-7 | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++14 | ||||
|       compiler: clang++-libc++ | ||||
|       env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - libc++-dev | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: g++-7 | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++17 | ||||
|       dist: bionic | ||||
|       compiler: clang++-libc++ | ||||
|       env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++ | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++ | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.5 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.5 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.5 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.5 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.5 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.5 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.5 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.5 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.6 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.6 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.6 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.6 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.6 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.6 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.6 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.6 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.7 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.7 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.7 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.7 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.7 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.7 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.7 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.7 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.8 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.8 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.8 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.8 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.8 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.8 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.8 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.8 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.9 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.9 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.9 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.9 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.9 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.9 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.9 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.9 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-4.0 | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-4.0 | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-4.0 | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-4.0 | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|             - libc++-dev | ||||
|  | ||||
|     - os: osx | ||||
|       compiler: clang++ | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03 | ||||
|       env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1 | ||||
|  | ||||
|     - os: osx | ||||
|       compiler: clang++ | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11 | ||||
|     - os: linux | ||||
|       env: CMAKE_TEST=1 | ||||
|       script: | ||||
|         - mkdir __build__ && cd __build__ | ||||
|         - cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=smart_ptr -DBUILD_TESTING=ON .. | ||||
|         - cmake --build . --target tests -- -k | ||||
|         - ctest --output-on-failure -R boost_smart_ptr | ||||
|  | ||||
|     - os: osx | ||||
|       compiler: clang++ | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14 | ||||
|     - os: linux | ||||
|       compiler: g++ | ||||
|       env: CMAKE_SUBDIR_TEST=1 | ||||
|       script: | ||||
|       - cd libs/smart_ptr/test/cmake_subdir_test && mkdir __build__ && cd __build__ | ||||
|       - cmake .. | ||||
|       - cmake --build . | ||||
|       - cmake --build . --target check | ||||
|  | ||||
|     - os: osx | ||||
|       compiler: clang++ | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++1z | ||||
|     - os: linux | ||||
|       env: CMAKE_INSTALL_TEST=1 | ||||
|       script: | ||||
|         - pip install --user cmake | ||||
|         - mkdir __build__ && cd __build__ | ||||
|         - cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=smart_ptr -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=~/.local .. | ||||
|         - cmake --build . --target install | ||||
|         - cd ../libs/smart_ptr/test/cmake_install_test && mkdir __build__ && cd __build__ | ||||
|         - cmake -DCMAKE_INSTALL_PREFIX=~/.local .. | ||||
|         - cmake --build . | ||||
|         - cmake --build . --target check | ||||
|  | ||||
| install: | ||||
|   - BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true | ||||
| @@ -511,26 +193,30 @@ install: | ||||
|   - git submodule init libs/assert | ||||
|   - git submodule init libs/atomic | ||||
|   - git submodule init libs/config | ||||
|   - git submodule init libs/container_hash | ||||
|   - 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/static_assert | ||||
|   - git submodule init libs/throw_exception | ||||
|   - git submodule init libs/type_traits | ||||
|   - git submodule init libs/detail | ||||
|   - git submodule init libs/integer | ||||
|   - git submodule init tools/build | ||||
|   - git submodule update | ||||
|   - git submodule init libs/headers | ||||
|   - git submodule init tools/boost_install | ||||
|   - git submodule init tools/cmake | ||||
|   - git submodule init libs/preprocessor | ||||
|   - git submodule init libs/bind | ||||
|   - git submodule update # no --jobs 3 on non-amd64 | ||||
|   - cp -r $TRAVIS_BUILD_DIR/* libs/smart_ptr | ||||
|   - ./bootstrap.sh | ||||
|   - ./b2 headers | ||||
|  | ||||
| script: | ||||
|   - |- | ||||
|     echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam | ||||
|   - ./b2 libs/smart_ptr/test toolset=$TOOLSET | ||||
|     echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam | ||||
|   - ./b2 -j3 libs/smart_ptr/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} | ||||
|  | ||||
| notifications: | ||||
|   email: | ||||
|   | ||||
							
								
								
									
										29
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| # Generated by `boostdep --cmake smart_ptr` | ||||
| # Copyright 2020, 2021 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| cmake_minimum_required(VERSION 3.8...3.20) | ||||
|  | ||||
| project(boost_smart_ptr VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) | ||||
|  | ||||
| add_library(boost_smart_ptr INTERFACE) | ||||
| add_library(Boost::smart_ptr ALIAS boost_smart_ptr) | ||||
|  | ||||
| target_include_directories(boost_smart_ptr INTERFACE include) | ||||
|  | ||||
| target_link_libraries(boost_smart_ptr | ||||
|   INTERFACE | ||||
|     Boost::assert | ||||
|     Boost::config | ||||
|     Boost::core | ||||
|     Boost::throw_exception | ||||
| ) | ||||
|  | ||||
| target_compile_features(boost_smart_ptr INTERFACE cxx_std_11) | ||||
|  | ||||
| if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") | ||||
|  | ||||
|   add_subdirectory(test) | ||||
|  | ||||
| endif() | ||||
| @@ -2,5 +2,5 @@ | ||||
|  | ||||
| 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) | ||||
| 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) | ||||
|   | ||||
							
								
								
									
										78
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								appveyor.yml
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| # Copyright 2016, 2017 Peter Dimov | ||||
| # Copyright 2016-2019 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| @@ -14,46 +14,66 @@ branches: | ||||
|  | ||||
| environment: | ||||
|   matrix: | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|       TOOLSET: msvc-9.0 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|       TOOLSET: msvc-10.0 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|       TOOLSET: msvc-11.0 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|       TOOLSET: msvc-12.0 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       TOOLSET: msvc-14.0 | ||||
|       ADDRMD: 32,64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 | ||||
|       TOOLSET: msvc-14.1 | ||||
|       CXXSTD: 14,17 | ||||
|       ADDRMD: 32,64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|       TOOLSET: msvc-14.2 | ||||
|       CXXSTD: 14 | ||||
|       ADDRMD: 32,64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|       TOOLSET: msvc-14.2 | ||||
|       CXXSTD: 17 | ||||
|       ADDRMD: 32,64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|       TOOLSET: msvc-14.2 | ||||
|       CXXSTD: 20 | ||||
|       ADDRMD: 32,64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|       TOOLSET: msvc-14.2 | ||||
|       CXXSTD: latest | ||||
|       ADDRMD: 32,64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|       TOOLSET: clang-win | ||||
|       CXXSTD: 14,17,latest | ||||
|       ADDRMD: 64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       ADDPATH: C:\cygwin\bin; | ||||
|       TOOLSET: gcc | ||||
|       CXXSTD: 11,14,1z | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       ADDPATH: C:\cygwin64\bin; | ||||
|       TOOLSET: gcc | ||||
|       CXXSTD: 11,14,1z | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 | ||||
|       ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin; | ||||
|       TOOLSET: gcc | ||||
|       CXXSTD: 11,14,17 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 | ||||
|       ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin; | ||||
|       TOOLSET: gcc | ||||
|       CXXSTD: 11,14,17 | ||||
|  | ||||
| install: | ||||
|   - set BOOST_BRANCH=develop | ||||
|   - if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master | ||||
|   - cd .. | ||||
|   - git clone -b %BOOST_BRANCH% https://github.com/boostorg/boost.git boost-root | ||||
|   - git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|   - cd boost-root | ||||
|   - 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/static_assert | ||||
|   - git submodule init libs/throw_exception | ||||
|   - git submodule init libs/type_traits | ||||
|   - git submodule init tools/build | ||||
|   - git submodule update | ||||
|   - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\smart_ptr | ||||
|   - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\smart_ptr\ | ||||
|   - git submodule update --init tools/boostdep | ||||
|   - python tools/boostdep/depinst/depinst.py smart_ptr | ||||
|   - cmd /c bootstrap | ||||
|   - b2 headers | ||||
|   - b2 -d0 headers | ||||
|  | ||||
| build: off | ||||
|  | ||||
| test_script: | ||||
|   - b2 libs/smart_ptr/test toolset=%TOOLSET% | ||||
|   - PATH=%ADDPATH%%PATH% | ||||
|   - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% | ||||
|   - if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD% | ||||
|   - b2 -j3 libs/smart_ptr/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker | ||||
|   | ||||
							
								
								
									
										23
									
								
								build.jam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								build.jam
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # Copyright 2023-2024 René Ferdinand Rivera Morell | ||||
| # Copyright 2024 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| require-b2 5.2 ; | ||||
|  | ||||
| constant boost_dependencies : | ||||
|     /boost/assert//boost_assert | ||||
|     /boost/config//boost_config | ||||
|     /boost/core//boost_core | ||||
|     /boost/throw_exception//boost_throw_exception | ||||
|     ; | ||||
|  | ||||
| project /boost/smart_ptr ; | ||||
|  | ||||
| explicit | ||||
|     [ alias boost_smart_ptr : : : : <include>include <library>$(boost_dependencies) ] | ||||
|     [ alias all : boost_smart_ptr test ] | ||||
|     ; | ||||
|  | ||||
| call-if : boost-library smart_ptr | ||||
|     ; | ||||
| @@ -5,8 +5,6 @@ | ||||
| # See accompanying file LICENSE_1_0.txt or copy at | ||||
| # http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| project doc/smart_ptr ; | ||||
|  | ||||
| import asciidoctor ; | ||||
|  | ||||
| html smart_ptr.html : smart_ptr.adoc ; | ||||
|   | ||||
| @@ -1,50 +0,0 @@ | ||||
| # Copyright 2017 Peter Dimov | ||||
| #  | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at | ||||
| # http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| import type ; | ||||
| import scanner ; | ||||
| import generators ; | ||||
| import boostbook ; | ||||
|  | ||||
| # File type | ||||
|  | ||||
| type.register ASCIIDOC : asciidoc adoc ; | ||||
|  | ||||
| # Define dependency scanner | ||||
|  | ||||
| class asciidoc-scanner : common-scanner | ||||
| { | ||||
|     rule pattern ( ) | ||||
|     { | ||||
|         return "include::([^[]+)\\[" ; | ||||
|     } | ||||
| } | ||||
|  | ||||
| scanner.register asciidoc-scanner : include ; | ||||
| type.set-scanner ASCIIDOC : asciidoc-scanner ; | ||||
|  | ||||
| # Define generators | ||||
|  | ||||
| generators.register-standard asciidoctor.asciidoc-to-html : ASCIIDOC : HTML ; | ||||
| generators.register-standard asciidoctor.asciidoc-to-pdf : ASCIIDOC : PDF ; | ||||
| # generators.register-standard asciidoctor.asciidoc-to-docbook : ASCIIDOC : DOCBOOK ; | ||||
|  | ||||
| # Define actions | ||||
|  | ||||
| actions asciidoc-to-html | ||||
| { | ||||
|     asciidoctor -b html -o $(1) $(2) | ||||
| } | ||||
|  | ||||
| actions asciidoc-to-pdf | ||||
| { | ||||
|     asciidoctor -r asciidoctor-pdf -b pdf -o $(1) $(2) | ||||
| } | ||||
|  | ||||
| actions asciidoc-to-docbook | ||||
| { | ||||
|     asciidoctor -b docbook -o $(1) $(2) | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| <style> | ||||
|  | ||||
| *:not(pre)>code { background: none; color: #600000; } | ||||
| :not(pre):not([class^=L])>code { background: none; color: #600000; } | ||||
| table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; } | ||||
|  | ||||
| </style> | ||||
|   | ||||
| @@ -14,38 +14,32 @@ Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes | ||||
| :idprefix: | ||||
| :listing-caption: Code Example | ||||
| :docinfo: private-footer | ||||
| :source-highlighter: rouge | ||||
| :source-language: c++ | ||||
|  | ||||
| :leveloffset: +1 | ||||
|  | ||||
| include::smart_ptr/introduction.adoc[] | ||||
|  | ||||
| include::smart_ptr/changelog.adoc[] | ||||
| include::smart_ptr/scoped_ptr.adoc[] | ||||
|  | ||||
| include::smart_ptr/scoped_array.adoc[] | ||||
|  | ||||
| include::smart_ptr/shared_ptr.adoc[] | ||||
|  | ||||
| include::smart_ptr/weak_ptr.adoc[] | ||||
|  | ||||
| include::smart_ptr/make_shared.adoc[] | ||||
|  | ||||
| include::smart_ptr/enable_shared_from_this.adoc[] | ||||
|  | ||||
| include::smart_ptr/enable_shared_from.adoc[] | ||||
| include::smart_ptr/make_unique.adoc[] | ||||
|  | ||||
| include::smart_ptr/allocate_unique.adoc[] | ||||
| include::smart_ptr/intrusive_ptr.adoc[] | ||||
|  | ||||
| include::smart_ptr/intrusive_ref_counter.adoc[] | ||||
|  | ||||
| include::smart_ptr/local_shared_ptr.adoc[] | ||||
|  | ||||
| include::smart_ptr/make_local_shared.adoc[] | ||||
|  | ||||
| include::smart_ptr/pointer_cast.adoc[] | ||||
|  | ||||
| include::smart_ptr/pointer_to_other.adoc[] | ||||
|  | ||||
| include::smart_ptr/atomic_shared_ptr.adoc[] | ||||
| include::smart_ptr/owner_less.adoc[] | ||||
| include::smart_ptr/owner_equal_to.adoc[] | ||||
| include::smart_ptr/owner_hash.adoc[] | ||||
|  | ||||
| // appendix | ||||
| include::smart_ptr/techniques.adoc[] | ||||
| @@ -67,7 +61,7 @@ This documentation is | ||||
| * Copyright 1999 Greg Colvin | ||||
| * Copyright 1999 Beman Dawes | ||||
| * Copyright 2002 Darin Adler | ||||
| * Copyright 2003-2017 Peter Dimov | ||||
| * Copyright 2003-2020 Peter Dimov | ||||
| * Copyright 2005, 2006 Ion Gaztañaga | ||||
| * Copyright 2008 Frank Mori Hess | ||||
| * Copyright 2012-2017 Glen Fernandes | ||||
|   | ||||
							
								
								
									
										335
									
								
								doc/smart_ptr/allocate_unique.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								doc/smart_ptr/allocate_unique.adoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,335 @@ | ||||
| //// | ||||
| Copyright 2019-2021 Glen Joseph Fernandes (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
|  | ||||
| See accompanying file LICENSE_1_0.txt or copy at | ||||
| http://www.boost.org/LICENSE_1_0.txt | ||||
| //// | ||||
|  | ||||
| [#allocate_unique] | ||||
| # allocate_unique: Creating unique_ptr | ||||
| :toc: | ||||
| :toc-title: | ||||
| :idprefix: allocate_unique_ | ||||
|  | ||||
| ## Description | ||||
|  | ||||
| The `allocate_unique` family of function templates provide convenient and safe | ||||
| ways to obtain a `std::unique_ptr` that manages a new object created using an | ||||
| allocator. | ||||
|  | ||||
| ## Rationale | ||||
|  | ||||
| The {cpp}14 standard introduced `std::make_unique` which used operator `new` to | ||||
| create new objects. However, there is no convenient facility in the standard | ||||
| library to use an allocator for the creation of the objects managed by | ||||
| `std::unique_ptr`. Users writing allocator aware code have often requested an | ||||
| `allocate_unique` factory function. This function is to `std::unique_ptr` what | ||||
| `std::allocate_shared` is to `std::shared_ptr`. | ||||
|  | ||||
| ## Synopsis | ||||
|  | ||||
| `allocate_unique` is defined in `<boost/smart_ptr/allocate_unique.hpp>`. | ||||
|  | ||||
| [subs=+quotes] | ||||
| ``` | ||||
| namespace boost { | ||||
|   template<class T, class A> | ||||
|   class alloc_deleter; | ||||
|  | ||||
|   template<class T, class A> | ||||
|   using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A>>; | ||||
|  | ||||
|   `// T is not an array` | ||||
|   template<class T, class A, class... Args> | ||||
|     std::unique_ptr<T, alloc_deleter<T, A>> | ||||
|       allocate_unique(const A& a, Args&&... args); | ||||
|  | ||||
|   `// T is not an array` | ||||
|   template<class T, class A> | ||||
|     std::unique_ptr<T, alloc_deleter<T, A>> | ||||
|       allocate_unique(const A& a, type_identity_t<T>&& v); | ||||
|  | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T, class A> | ||||
|     std::unique_ptr<T, alloc_deleter<T, A>> | ||||
|       allocate_unique(const A& a, std::size_t n); | ||||
|  | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T, class A> | ||||
|     std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>> | ||||
|       allocate_unique(const A& a); | ||||
|  | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T, class A> | ||||
|     std::unique_ptr<T, alloc_deleter<T, A>> | ||||
|       allocate_unique(const A& a, std::size_t n, const remove_extent_t<T>& v); | ||||
|  | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T, class A> | ||||
|     std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>> | ||||
|       allocate_unique(const A& a, const remove_extent_t<T>& v); | ||||
|  | ||||
|   `// T is not an array` | ||||
|   template<class T, class A> | ||||
|     std::unique_ptr<T, alloc_noinit_deleter<T, A>> | ||||
|       allocate_unique_noinit(const A& a); | ||||
|  | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T, class A> | ||||
|     std::unique_ptr<T, alloc_noinit_deleter<T, A>> | ||||
|       allocate_unique_noinit(const A& a, std::size_t n); | ||||
|  | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T, class A> | ||||
|     std::unique_ptr<remove_extent_t<T>[], alloc_noinit_deleter<T, A>> | ||||
|       allocate_unique_noinit(const A& a); | ||||
|  | ||||
|   template<class T, class U, class A> | ||||
|     allocator_pointer_t<allocator_rebind_t<A, remove_cv_t<remove_extent_t<T>>>> | ||||
|       get_allocator_pointer(const std::unique_ptr<T, | ||||
|         alloc_deleter<U, A>>& p) noexcept; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Common Requirements | ||||
|  | ||||
| The common requirements that apply to all `allocate_unique` and | ||||
| `allocate_unique_noinit` overloads, unless specified otherwise, are described | ||||
| below. | ||||
|  | ||||
| Requires:: `A` shall be an _allocator_. The copy constructor and destructor | ||||
| of `A` shall not throw exceptions. | ||||
|  | ||||
| Effects:: Allocates memory for an object of type `T` or `n` objects of `U` | ||||
| (if `T` is an array type of the form `U[]` and  `n` is determined by | ||||
| arguments, as specified by the concrete overload). The object is initialized | ||||
| from arguments as specified by the concrete overload. Uses a rebound copy of | ||||
| `a` (for an unspecified `value_type`) to allocate memory. If an exception is | ||||
| thrown, the functions have no effect. | ||||
|  | ||||
| Returns:: A `std::unique_ptr` instance that stores and owns the address of the | ||||
| newly constructed object. | ||||
|  | ||||
| Postconditions:: `r.get() != 0`, where `r` is the return value. | ||||
|  | ||||
| Throws:: An exception thrown from `A::allocate`, or from the initialization of | ||||
| the object. | ||||
|  | ||||
| Remarks:: | ||||
| * When an object of an array type is specified to be initialized to a value of | ||||
| the same type `v`, this shall be interpreted to mean that each array element | ||||
| of the object is initialized to the corresponding element from `v`. | ||||
| * When an object of an array type is specified to be value-initialized, this | ||||
| shall be interpreted to mean that each array element of the object is | ||||
| value-initialized. | ||||
| * When a (sub)object of non-array type `U` is specified to be initialized to a | ||||
| value `v`, or constructed from `args\...`, `allocate_unique` shall perform this | ||||
| initialization via the expression | ||||
| `std::allocator_traits<A2>::construct(a2, p, expr)` (where `_expr_` is `v` or | ||||
| `std::forward<Args>(args)\...)` respectively), `p` points to storage suitable | ||||
| to hold an object of type `U`, and `a2` of type `A2` is a potentially rebound | ||||
| copy of `a`. | ||||
| * When a (sub)object of non-array type `U` is specified to be | ||||
| default-initialized, `allocate_unique_noinit` shall perform this initialization | ||||
| via the expression `::new(p) U`, where `p` has type `void*` and points to | ||||
| storage suitable to hold an object of type `U`. | ||||
| * When a (sub)object of non-array type `U` is specified to be | ||||
| value-initialized, `allocate_unique` shall perform this initialization via the | ||||
| expression `std::allocator_traits<A2>::construct(a2, p)`, where `p` points to | ||||
| storage suitable to hold an object of type `U` and `a2` of type `A2` is a | ||||
| potentially rebound copy of `a`. | ||||
| * Array elements are initialized in ascending order of their addresses. | ||||
| * When the lifetime of the object managed by the return value ends, or when the | ||||
| initialization of an array element throws an exception, the initialized | ||||
| elements should be destroyed in the reverse order of their construction. | ||||
|  | ||||
| ## Free Functions | ||||
|  | ||||
| ``` | ||||
| template<class T, class A, class... Args> | ||||
|   std::unique_ptr<T, alloc_deleter<T, A>> | ||||
|     allocate_unique(const A& a, Args&&... args); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: A `std::unique_ptr` to an object of type `T`, constructed from | ||||
| `args\...`. | ||||
| Examples:: | ||||
| * `auto p = allocate_unique<int>(a);` | ||||
| * `auto p = allocate_unique<std::vector<int>>(a, 16, 1);` | ||||
|  | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   std::unique_ptr<T, alloc_deleter<T, A>> | ||||
|     allocate_unique(const A& a, type_identity_t<T>&& v); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: A `std::unique_ptr` to an object of type `T`, constructed from `v`. | ||||
| Example:: `auto p = allocate_unique<std::vector<int>>(a, {1, 2});` | ||||
|  | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   std::unique_ptr<T, alloc_deleter<T, A>> | ||||
|     allocate_unique(const A& a, std::size_t n); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `std::unique_ptr` to a sequence of `n` value-initialized objects of | ||||
| type `remove_extent_t<T>`. | ||||
| Examples:: | ||||
| * `auto p = allocate_unique<double[]>(a, 1024);` | ||||
| * `auto p = allocate_unique<double[][2][2]>(a, 6);` | ||||
|  | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>> | ||||
|     allocate_unique(const A& a); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of known bounds. | ||||
| Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` value-initialized | ||||
| objects of type `remove_extent_t<T>`. | ||||
| Examples:: | ||||
| * `auto p = allocate_unique<double[1024]>(a);` | ||||
| * `auto p = allocate_unique<double[6][2][2]>(a);` | ||||
|  | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   std::unique_ptr<T, alloc_deleter<T, A>> | ||||
|     allocate_unique(const A& a, std::size_t n, const remove_extent_t<T>& v); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `std::unique_ptr` to a sequence of `n` objects of type | ||||
| `remove_extent_t<T>`, each initialized to `v`. | ||||
| Examples:: | ||||
| * `auto p = allocate_unique<double[]>(a, 1024, 1.0);` | ||||
| * `auto p = allocate_unique<double[][2]>(a, 6, {1.0, 0.0});` | ||||
| * `auto p = allocate_unique<std::vector<int>[]>(a, 4, {1, 2});` | ||||
|  | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>> | ||||
|     allocate_unique(const A& a, const remove_extent_t<T>& v); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of known bounds. | ||||
| Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` objects of type | ||||
| `remove_extent_t<T>`, each initialized to `v`. | ||||
| Examples:: | ||||
| * `auto p = allocate_unique<double[1024]>(a, 1.0);` | ||||
| * `auto p = allocate_unique<double[6][2]>(a, {1.0, 0.0});` | ||||
| * `auto p = allocate_unique<std::vector<int>[4]>(a, {1, 2});` | ||||
|  | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   std::unique_ptr<T, alloc_noinit_deleter<T, A>> | ||||
|     allocate_unique_noinit(const A& a); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: A `std::unique_ptr` to a default-initialized object of type `T`. | ||||
| Example:: `auto p = allocate_unique_noinit<double>(a);` | ||||
|  | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   std::unique_ptr<T, alloc_noinit_deleter<T, A>> | ||||
|     allocate_unique_noinit(const A& a, std::size_t n); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `std::unique_ptr` to a sequence of `n` default-initialized objects | ||||
| of type `remove_extent_t<T>`. | ||||
| Example:: `auto p = allocate_unique_noinit<double[]>(a, 1024);` | ||||
|  | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   std::unique_ptr<remove_extent_t<T>, alloc_noinit_deleter<T, A>> | ||||
|     allocate_unique_noinit(const A& a); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of known bounds. | ||||
| Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` | ||||
| default-initialized objects of type `remove_extent_t<T>`. | ||||
| Example:: `auto p = allocate_unique_noinit<double[1024]>(a);` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U, class A> | ||||
|   allocator_pointer_t<allocator_rebind_t<A, remove_cv_t<remove_extent_t<T>>>> | ||||
|     get_allocator_pointer(const std::unique_ptr<T, | ||||
|       alloc_deleter<U, A>>& p) noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The allocator pointer to the allocation. | ||||
| Example:: `auto r = boost::get_allocator_ptr(p);` | ||||
|  | ||||
| ## Deleter | ||||
|  | ||||
| Class template `alloc_deleter` is the deleter used by the `allocate_unique` | ||||
| functions. | ||||
|  | ||||
| ### Synopsis | ||||
|  | ||||
| [subs=+quotes] | ||||
| ``` | ||||
| template<class T, class A> | ||||
| class alloc_deleter { | ||||
| public: | ||||
|   using pointer = `unspecified`; | ||||
|  | ||||
|   explicit alloc_deleter(const A& a) noexcept; | ||||
|  | ||||
|   void operator()(pointer p); | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| ### Members | ||||
|  | ||||
| [subs=+quotes] | ||||
| ``` | ||||
| using pointer = `unspecified`; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| A type that satisfies _NullablePointer_. | ||||
|  | ||||
| ``` | ||||
| explicit alloc_deleter(const A& a) noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Initializes the stored allocator from `a`. | ||||
|  | ||||
| ``` | ||||
| void operator()(pointer p); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Destroys the objects and deallocates the storage referenced by `p`, | ||||
| using the stored allocator. | ||||
							
								
								
									
										56
									
								
								doc/smart_ptr/changelog.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								doc/smart_ptr/changelog.adoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| //// | ||||
| Copyright 2019-2025 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 | ||||
| //// | ||||
|  | ||||
| [#changelog] | ||||
| # Revision History | ||||
| :toc: | ||||
| :toc-title: | ||||
| :idprefix: changelog_ | ||||
|  | ||||
| ## Changes in 1.88.0 | ||||
|  | ||||
| * Fix `operator<<` for wide streams (accidentally broken in 1.87.0) | ||||
|  | ||||
| ## Changes in 1.87.0 | ||||
|  | ||||
| * {cpp}03 is no longer supported, a {cpp}11 compiler is required. | ||||
|   This includes GCC 4.8 or later, and MSVC 14.0 or later. | ||||
| * The functionality enabled by the macros `BOOST_SP_ENABLE_DEBUG_HOOKS`, | ||||
|   `BOOST_SP_USE_STD_ALLOCATOR`, `BOOST_SP_USE_QUICK_ALLOCATOR`, | ||||
|   `BOOST_AC_USE_SPINLOCK`, `BOOST_AC_USE_PTHREADS`, `BOOST_SP_USE_SPINLOCK`, | ||||
|   and `BOOST_SP_USE_PTHREADS` has been deprecated and support for it | ||||
|   will be removed in a future release. | ||||
|  | ||||
| ## Changes in 1.79.0 | ||||
|  | ||||
| * Added `get_allocator_pointer` | ||||
|  | ||||
| ## Changes in 1.74.0 | ||||
|  | ||||
| * Added `owner_equals` to `shared_ptr`, `weak_ptr`, `local_shared_ptr` | ||||
| * Added `owner_hash_value` to `shared_ptr`, `weak_ptr` | ||||
| * Added `owner_equal_to`, `owner_hash` | ||||
| * Added `std::hash` specializations for `shared_ptr`, `local_shared_ptr` | ||||
| * Added `boost::hash` support to, and `std::hash`, `std::equal_to` | ||||
|   specializations for, `weak_ptr` | ||||
|  | ||||
| ## Changes in 1.72.0 | ||||
|  | ||||
| * Added `allocate_unique` | ||||
|  | ||||
| ## Changes in 1.71.0 | ||||
|  | ||||
| * Added aliasing constructors to `weak_ptr` | ||||
| * Added `weak_ptr<T>::empty()` | ||||
| * Added `enable_shared_from`, `shared_from`, and `weak_from` | ||||
|  | ||||
| ## Changes in 1.65.0 | ||||
|  | ||||
| * Added `atomic_shared_ptr` | ||||
| * Added `local_shared_ptr`, `make_local_shared` | ||||
							
								
								
									
										89
									
								
								doc/smart_ptr/enable_shared_from.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								doc/smart_ptr/enable_shared_from.adoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| //// | ||||
| Copyright 2002, 2003, 2015, 2017, 2019 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 | ||||
| //// | ||||
|  | ||||
| [#enable_shared_from] | ||||
| # enable_shared_from | ||||
| :toc: | ||||
| :toc-title: | ||||
| :idprefix: enable_shared_from_ | ||||
|  | ||||
| ## Description | ||||
|  | ||||
| `enable_shared_from` is used as a base class that allows a `shared_ptr` or a | ||||
| `weak_ptr` to be obtained given a raw pointer to the object, by using the | ||||
| functions `shared_from` and `weak_from`. | ||||
|  | ||||
| `enable_shared_from` differs from `enable_shared_from_this<T>` by the fact | ||||
| that it's not a template, and is its recommended replacement for new code. | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ``` | ||||
| #include <boost/smart_ptr/enable_shared_from.hpp> | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <cassert> | ||||
|  | ||||
| class Y: public boost::enable_shared_from | ||||
| { | ||||
| public: | ||||
|  | ||||
|     boost::shared_ptr<Y> f() | ||||
|     { | ||||
|         return boost::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 | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Synopsis | ||||
|  | ||||
| `enable_shared_from` is defined in `<boost/smart_ptr/enable_shared_from.hpp>`. | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
|  | ||||
|   class enable_shared_from: public enable_shared_from_this<enable_shared_from> | ||||
|   { | ||||
|   }; | ||||
|  | ||||
|   template<class T> shared_ptr<T> shared_from( T * p ); | ||||
|   template<class T> weak_ptr<T> weak_from( T * p ) noexcept; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Functions | ||||
|  | ||||
| ``` | ||||
| template<class T> shared_ptr<T> shared_from( T * p ); | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `shared_ptr<T>( p\->enable_shared_from::shared_from_this(), p )`. | ||||
|  | ||||
| NOTE: Throws `bad_weak_ptr` when `p` is not owned by a `shared_ptr`. | ||||
|  | ||||
| ``` | ||||
| template<class T> weak_ptr<T> weak_from( T * p ) noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `weak_ptr<T>( p\->enable_shared_from::weak_from_this(), p )`. | ||||
|  | ||||
| NOTE: Unlike `shared_from(this)`, `weak_from(this)` is valid in a destructor | ||||
|       and returns a `weak_ptr` that is `expired()` but still shares ownership | ||||
|       with other `weak_ptr` instances (if any) that refer to the object. | ||||
| @@ -142,3 +142,7 @@ template<class T> weak_ptr<T const> weak_from_this() const noexcept; | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `weak_this_`. | ||||
|  | ||||
| NOTE: Unlike `shared_from_this()`, `weak_from_this()` is valid in a destructor | ||||
|       and returns a `weak_ptr` that is `expired()` but still shares ownership | ||||
|       with other `weak_ptr` instances (if any) that refer to the object. | ||||
|   | ||||
| @@ -111,3 +111,7 @@ Glen Fernandes rewrote `allocate_shared` and `make_shared` for arrays for a more | ||||
| Peter Dimov and Glen Fernandes rewrote the documentation in Asciidoc format. | ||||
|  | ||||
| Peter Dimov added `atomic_shared_ptr` and `local_shared_ptr`. | ||||
|  | ||||
| ## August 2019 | ||||
|  | ||||
| Glen Fernandes implemented `allocate_unique` for scalars and arrays. | ||||
|   | ||||
| @@ -11,7 +11,9 @@ http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| [#introduction] | ||||
| # Introduction | ||||
| :idprefix: intro | ||||
| :toc: | ||||
| :toc-title: | ||||
| :idprefix: intro_ | ||||
|  | ||||
| Smart pointers are objects which store pointers to dynamically allocated (heap) objects. | ||||
| They behave much like built-in {cpp} pointers except that they automatically delete the object | ||||
| @@ -29,7 +31,7 @@ This library provides six smart pointer class templates: | ||||
| * `<<scoped_ptr,scoped_ptr>>`, used to contain ownership of a dynamically allocated object to the current scope; | ||||
| * `<<scoped_array,scoped_array>>`, which provides scoped ownership for a dynamically allocated array; | ||||
| * `<<shared_ptr,shared_ptr>>`, a versatile tool for managing shared ownership of an object or array; | ||||
| * `<<weak_ptr,weak_ptr>>`, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr; | ||||
| * `<<weak_ptr,weak_ptr>>`, a non-owning observer to a `shared_ptr`-managed object that can be promoted temporarily to `shared_ptr`; | ||||
| * `<<intrusive_ptr,intrusive_ptr>>`, a pointer to objects with an embedded reference count; | ||||
| * `<<local_shared_ptr,local_shared_ptr>>`, providing shared ownership within a single thread. | ||||
|  | ||||
| @@ -37,9 +39,11 @@ This library provides six smart pointer class templates: | ||||
|  | ||||
| In addition, the library contains the following supporting utility functions and classes: | ||||
|  | ||||
| * `<<make_shared,make_shared>>`, a factory function for creating objects that returns a `shared_ptr`; | ||||
| * `<<make_shared,make_shared>>` and `allocate_shared`, factory functions for creating objects that return a `shared_ptr`; | ||||
| * `<<make_unique,make_unique>>`, a factory function returning `std::unique_ptr`; | ||||
| * `<<allocate_unique,allocate_unique>>`, a factory function for creating objects using an allocator that returns a `std::unique_ptr`; | ||||
| * `<<enable_shared_from_this,enable_shared_from_this>>`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`; | ||||
| * `<<enable_shared_from,enable_shared_from>>`, a newer and better replacement for `enable_shared_from_this`; | ||||
| * `<<pointer_to_other,pointer_to_other>>`, a helper trait for converting one smart pointer type to another; | ||||
| * `<<pointer_cast,static_pointer_cast>>` and companions, generic smart pointer casts; | ||||
| * `<<intrusive_ref_counter,intrusive_ref_counter>>`, a helper base class containing a reference count. | ||||
|   | ||||
| @@ -54,12 +54,18 @@ namespace boost { | ||||
|     intrusive_ptr(intrusive_ptr const & r); | ||||
|     template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r); | ||||
|  | ||||
|     intrusive_ptr(intrusive_ptr && r); | ||||
|     template<class Y> intrusive_ptr(intrusive_ptr<Y> && r); | ||||
|  | ||||
|     ~intrusive_ptr(); | ||||
|  | ||||
|     intrusive_ptr & operator=(intrusive_ptr const & r); | ||||
|     template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r); | ||||
|     intrusive_ptr & operator=(T * r); | ||||
|  | ||||
|     intrusive_ptr & operator=(intrusive_ptr && r); | ||||
|     template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> && r); | ||||
|  | ||||
|     void reset(); | ||||
|     void reset(T * r); | ||||
|     void reset(T * r, bool add_ref); | ||||
| @@ -71,7 +77,7 @@ namespace boost { | ||||
|  | ||||
|     explicit operator bool () const noexcept; | ||||
|  | ||||
|     void swap(intrusive_ptr & b) noexept; | ||||
|     void swap(intrusive_ptr & b) noexcept; | ||||
|   }; | ||||
|  | ||||
|   template<class T, class U> | ||||
| @@ -92,8 +98,8 @@ namespace boost { | ||||
|   template<class T, class U> | ||||
|     bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept; | ||||
|  | ||||
|   template<class T, class U> | ||||
|     bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept; | ||||
|   template<class T> | ||||
|     bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept; | ||||
|  | ||||
|   template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept; | ||||
|  | ||||
| @@ -155,9 +161,22 @@ template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r); | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: `if(r.get() != 0) intrusive_ptr_add_ref(r.get());`. | ||||
| Effects:: `T * p = r.get(); if(p != 0) intrusive_ptr_add_ref(p);`. | ||||
| Postconditions:: `get() == r.get()`. | ||||
|  | ||||
| ``` | ||||
| intrusive_ptr(intrusive_ptr && r); | ||||
| ``` | ||||
| ``` | ||||
| template<class Y> intrusive_ptr(intrusive_ptr<Y> && r); | ||||
| ``` | ||||
|  | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Postconditions:: | ||||
|   `get()` equals the old value of `r.get()`. `r.get() == 0`. | ||||
|  | ||||
| ### destructor | ||||
|  | ||||
| ``` | ||||
| @@ -167,7 +186,8 @@ Postconditions:: `get() == r.get()`. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: `if(get() != 0) intrusive_ptr_release(get());`. | ||||
| Effects:: | ||||
|   `if(get() != 0) intrusive_ptr_release(get());`. | ||||
|  | ||||
| ### assignment | ||||
|  | ||||
| @@ -187,6 +207,19 @@ intrusive_ptr & operator=(T * r); | ||||
| Effects:: Equivalent to `intrusive_ptr(r).swap(*this)`. | ||||
| Returns:: `*this`. | ||||
|  | ||||
| ``` | ||||
| intrusive_ptr & operator=(intrusive_ptr && r); | ||||
| ``` | ||||
| ``` | ||||
| template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> && r); | ||||
| ``` | ||||
|  | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `intrusive_ptr(std::move(r)).swap(*this)`. | ||||
| Returns:: `*this`. | ||||
|  | ||||
| ### reset | ||||
|  | ||||
| ``` | ||||
| @@ -214,7 +247,8 @@ void reset(T * r, bool add_ref); | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`. | ||||
| Effects:: | ||||
|   Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`. | ||||
|  | ||||
| ### indirection | ||||
|  | ||||
| @@ -247,7 +281,8 @@ T * get() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: the stored pointer. | ||||
| Returns:: | ||||
|   the stored pointer. | ||||
|  | ||||
| ### detach | ||||
|  | ||||
| @@ -294,7 +329,8 @@ void swap(intrusive_ptr & b) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Exchanges the contents of the two smart pointers. | ||||
| Effects:: | ||||
|   Exchanges the contents of the two smart pointers. | ||||
|  | ||||
| ## Free Functions | ||||
|  | ||||
| @@ -361,8 +397,8 @@ template<class T, class U> | ||||
| Returns:: `a != b.get()`. | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> | ||||
|   bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept; | ||||
| template<class T> | ||||
|   bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept; | ||||
| ``` | ||||
|  | ||||
| [none] | ||||
| @@ -381,7 +417,8 @@ template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `a.swap(b)`. | ||||
| Effects:: | ||||
|   Equivalent to `a.swap(b)`. | ||||
|  | ||||
| ### get_pointer | ||||
|  | ||||
| @@ -406,7 +443,8 @@ template<class T, class U> | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `intrusive_ptr<T>(static_cast<T*>(r.get()))`. | ||||
| Returns:: | ||||
|   `intrusive_ptr<T>(static_cast<T*>(r.get()))`. | ||||
|  | ||||
| ### const_pointer_cast | ||||
|  | ||||
| @@ -418,7 +456,8 @@ template<class T, class U> | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `intrusive_ptr<T>(const_cast<T*>(r.get()))`. | ||||
| Returns:: | ||||
|   `intrusive_ptr<T>(const_cast<T*>(r.get()))`. | ||||
|  | ||||
| ### dynamic_pointer_cast | ||||
|  | ||||
| @@ -430,7 +469,8 @@ template<class T, class U> | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `intrusive_ptr<T>(dynamic_cast<T*>(r.get()))`. | ||||
| Returns:: | ||||
|   `intrusive_ptr<T>(dynamic_cast<T*>(r.get()))`. | ||||
|  | ||||
| ### operator<< | ||||
|  | ||||
|   | ||||
| @@ -78,12 +78,13 @@ namespace boost { | ||||
| ``` | ||||
| intrusive_ref_counter() noexcept; | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| intrusive_ref_counter(const intrusive_ref_counter&) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Postconditions::: `use_count() == 0`. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Postconditions:: `use_count() == 0`. | ||||
|  | ||||
| NOTE: The pointer to the constructed object is expected to be passed to | ||||
| `intrusive_ptr` constructor, assignment operator or `reset` method, which | ||||
| @@ -94,8 +95,10 @@ would increment the reference counter. | ||||
| ``` | ||||
| ~intrusive_ref_counter(); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Destroys the counter object. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Destroys the counter object. | ||||
|  | ||||
| NOTE: The destructor is protected so that the object can only be destroyed | ||||
| through the `Derived` class. | ||||
| @@ -105,16 +108,21 @@ through the `Derived` class. | ||||
| ``` | ||||
| intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Does nothing, reference counter is not modified. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: | ||||
|   Does nothing, reference counter is not modified. | ||||
|  | ||||
| ### use_count | ||||
|  | ||||
| ``` | ||||
| unsigned int use_count() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: The current value of the reference counter. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The current value of the reference counter. | ||||
|  | ||||
| NOTE: The returned value may not be actual in multi-threaded applications. | ||||
|  | ||||
| @@ -127,8 +135,11 @@ template<class Derived, class CounterPolicy> | ||||
|   void intrusive_ptr_add_ref( | ||||
|     const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Increments the reference counter. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: | ||||
|   Increments the reference counter. | ||||
|  | ||||
| ### intrusive_ptr_release | ||||
|  | ||||
| @@ -137,6 +148,8 @@ template<class Derived, class CounterPolicy> | ||||
|   void intrusive_ptr_release( | ||||
|     const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Decrements the reference counter. If the reference counter reaches | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Decrements the reference counter. If the reference counter reaches | ||||
| 0, calls `delete static_cast<const Derived*>(p)`. | ||||
|   | ||||
| @@ -124,7 +124,7 @@ namespace boost { | ||||
|     template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept; | ||||
|  | ||||
|     // accessors | ||||
|      | ||||
|  | ||||
|     T & operator*() const noexcept; // only valid when T is not an array type | ||||
|     T * operator->() const noexcept; // only valid when T is not an array type | ||||
|  | ||||
| @@ -143,12 +143,16 @@ namespace boost { | ||||
|     template<class Y> operator weak_ptr<Y>() const noexcept; | ||||
|  | ||||
|     // swap | ||||
|      | ||||
|  | ||||
|     void swap(local_shared_ptr & b) noexcept; | ||||
|  | ||||
|     // owner_before | ||||
|      | ||||
|     template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept; | ||||
|  | ||||
|     template<class Y> bool owner_before(local_shared_ptr<Y> const & r) const noexcept; | ||||
|  | ||||
|     // owner_equals | ||||
|  | ||||
|     template<class Y> bool owner_equals(local_shared_ptr<Y> const & r) const noexcept; | ||||
|   }; | ||||
|  | ||||
|   // comparisons | ||||
| @@ -459,7 +463,8 @@ template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcep | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`. | ||||
| Effects:: | ||||
|   Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`. | ||||
|  | ||||
| ### indirection | ||||
| ``` | ||||
| @@ -497,7 +502,8 @@ element_type * get() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The stored pointer. | ||||
| Returns:: | ||||
|   The stored pointer. | ||||
|  | ||||
| ### local_use_count | ||||
| ``` | ||||
| @@ -506,7 +512,8 @@ long local_use_count() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The number of `local_shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty. | ||||
| Returns:: | ||||
|   The number of `local_shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty. | ||||
|  | ||||
| ### conversions | ||||
| ``` | ||||
| @@ -538,16 +545,28 @@ void swap(local_shared_ptr & b) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Exchanges the contents of the two smart pointers. | ||||
| Effects:: | ||||
|   Exchanges the contents of the two smart pointers. | ||||
|  | ||||
| ### owner_before | ||||
| ``` | ||||
| template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept; | ||||
| template<class Y> bool owner_before(local_shared_ptr<Y> const & r) const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: See the description of `operator<`. | ||||
| Returns:: | ||||
|   See the description of `operator<`. | ||||
|  | ||||
| ### owner_equals | ||||
| ``` | ||||
| template<class Y> bool owner_equals(local_shared_ptr<Y> const & r) const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   `true` if and only if `*this` and `r` share ownership or are both empty. | ||||
|  | ||||
| ## Free Functions | ||||
|  | ||||
| @@ -631,7 +650,8 @@ template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) no | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `a.swap(b)`. | ||||
| Effects:: | ||||
|   Equivalent to `a.swap(b)`. | ||||
|  | ||||
| ### get_pointer | ||||
| ``` | ||||
| @@ -716,4 +736,3 @@ template<class D, class T> | ||||
| * {blank} | ||||
| + | ||||
| Returns:: If `*this` owns a `shared_ptr` instance `p`, `get_deleter<D>( p )`, otherwise 0. | ||||
|  | ||||
|   | ||||
| @@ -27,25 +27,25 @@ are analogous to `make_shared` and `allocate_shared` for `shared_ptr`. | ||||
| [subs=+quotes] | ||||
| ``` | ||||
| namespace boost { | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T, class... Args> | ||||
|     local_shared_ptr<T> make_local_shared(Args&&... args); | ||||
|   template<class T, class A, class... Args> | ||||
|     local_shared_ptr<T> allocate_local_shared(const A& a, Args&&... args); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     local_shared_ptr<T> make_local_shared(std::size_t n); | ||||
|   template<class T, class A> | ||||
|     local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T> | ||||
|     local_shared_ptr<T> make_local_shared(); | ||||
|   template<class T, class A> | ||||
|     local_shared_ptr<T> allocate_local_shared(const A& a); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     local_shared_ptr<T> make_local_shared(std::size_t n, | ||||
|       const remove_extent_t<T>& v); | ||||
| @@ -53,20 +53,20 @@ namespace boost { | ||||
|     local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n, | ||||
|       const remove_extent_t<T>& v); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T> | ||||
|     local_shared_ptr<T> make_local_shared(const remove_extent_t<T>& v); | ||||
|   template<class T, class A> | ||||
|     local_shared_ptr<T> allocate_local_shared(const A& a, | ||||
|       const remove_extent_t<T>& v); | ||||
|  | ||||
|   `// only if T is not an array type of the form U[]` | ||||
|   `// T is not an array of known bounds` | ||||
|   template<class T> | ||||
|     local_shared_ptr<T> make_local_shared_noinit(); | ||||
|   template<class T, class A> | ||||
|     local_shared_ptr<T> allocate_local_shared_noinit(const A& a); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     local_shared_ptr<T> make_local_shared_noinit(std::size_t n); | ||||
|   template<class T, class A> | ||||
|   | ||||
| @@ -55,43 +55,43 @@ types. | ||||
| [subs=+quotes] | ||||
| ``` | ||||
| namespace boost { | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T, class... Args> | ||||
|     shared_ptr<T> make_shared(Args&&... args); | ||||
|   template<class T, class A, class... Args> | ||||
|     shared_ptr<T> allocate_shared(const A& a, Args&&... args); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared(std::size_t n); | ||||
|   template<class T, class A> | ||||
|     shared_ptr<T> allocate_shared(const A& a, std::size_t n); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared(); | ||||
|   template<class T, class A> | ||||
|     shared_ptr<T> allocate_shared(const A& a); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> shared_ptr<T> | ||||
|     make_shared(std::size_t n, const remove_extent_t<T>& v); | ||||
|   template<class T, class A> shared_ptr<T> | ||||
|     allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared(const remove_extent_t<T>& v); | ||||
|   template<class T, class A> | ||||
|     shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v); | ||||
|  | ||||
|   `// only if T is not an array type of the form U[]` | ||||
|   `// T is not an array of unknown bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared_noinit(); | ||||
|   template<class T, class A> | ||||
|     shared_ptr<T> allocate_shared_noinit(const A& a); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared_noinit(std::size_t n); | ||||
|   template<class T, class A> | ||||
| @@ -144,7 +144,7 @@ perform this initialization via the expression | ||||
| `std::allocator_traits<A2>::construct(a2, p, expr)` (where | ||||
| `_expr_` is `v` or `std::forward<Args>(args)\...)` respectively), `p` | ||||
| points to storage suitable to hold an object of type `U`, and `a2` of | ||||
| type `A2` is a rebound copy `a` such that its `value_type` is `U`. | ||||
| type `A2` is a potentially rebound copy of `a`. | ||||
| * When a (sub)object of non-array type `U` is specified to be | ||||
| default-initialized, `make_shared_noinit` and `allocate_shared_noinit` shall | ||||
| perform this initialization via the expression `::new(p) U`, where | ||||
| @@ -158,7 +158,7 @@ storage suitable to hold an object of type `U`. | ||||
| value-initialized, `allocate_shared` shall perform this initialization via the | ||||
| expression `std::allocator_traits<A2>::construct(a2, p)`, where | ||||
| `p` points to storage suitable to hold an object of type `U` and `a2` of | ||||
| type `A2` is a rebound copy of `a` such that its value_type is `U`. | ||||
| type `A2` is a potentially rebound copy of `a`. | ||||
| * Array elements are initialized in ascending order of their addresses. | ||||
| * When the lifetime of the object managed by the return value ends, or when | ||||
| the initialization of an array element throws an exception, the initialized | ||||
| @@ -174,17 +174,17 @@ the reference counts. | ||||
| template<class T, class... Args> | ||||
|   shared_ptr<T> make_shared(Args&&... args); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A, class... Args> | ||||
|   shared_ptr<T> allocate_shared(const A& a, Args&&... args); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type. | ||||
| Returns::: A `shared_ptr` to an object of type `T`, constructed from | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: A `shared_ptr` to an object of type `T`, constructed from | ||||
| `args\...`. | ||||
| Examples::: | ||||
| Examples:: | ||||
| * `auto p = make_shared<int>();` | ||||
| * `auto p = make_shared<std::vector<int> >(16, 1);` | ||||
|  | ||||
| @@ -192,17 +192,17 @@ Examples::: | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared(std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared(const A& a, std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `n` value-initialized objects of | ||||
| type `U`. | ||||
| Examples::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `n` value-initialized objects of | ||||
| type `remove_extent_t<T>`. | ||||
| Examples:: | ||||
| * `auto p = make_shared<double[]>(1024);` | ||||
| * `auto p = make_shared<double[][2][2]>(6);` | ||||
|  | ||||
| @@ -210,17 +210,17 @@ Examples::: | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared(); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared(const A& a); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[N]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `N` value-initialized objects of | ||||
| type `U`. | ||||
| Examples::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of known bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `extent_v<T>` value-initialized | ||||
| objects of type `remove_extent_t<T>`. | ||||
| Examples:: | ||||
| * `auto p = make_shared<double[1024]>();` | ||||
| * `auto p = make_shared<double[6][2][2]>();` | ||||
|  | ||||
| @@ -228,17 +228,17 @@ Examples::: | ||||
| template<class T> shared_ptr<T> | ||||
|   make_shared(std::size_t n, const remove_extent_t<T>& v); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> shared_ptr<T> | ||||
|   allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `n` objects of type `U`, each | ||||
| initialized to `v`. | ||||
| Examples::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `n` objects of type | ||||
| `remove_extent_t<T>`, each initialized to `v`. | ||||
| Examples:: | ||||
| * `auto p = make_shared<double[]>(1024, 1.0);` | ||||
| * `auto p = make_shared<double[][2]>(6, {1.0, 0.0});` | ||||
| * `auto p = make_shared<std::vector<int>[]>(4, {1, 2});` | ||||
| @@ -247,17 +247,17 @@ Examples::: | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared(const remove_extent_t<T>& v); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[N]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `N` objects of type `U`, each | ||||
| initialized to `v`. | ||||
| Examples::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of known bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `extent_v<T>` objects of type | ||||
| `remove_extent_t<T>`, each initialized to `v`. | ||||
| Examples:: | ||||
| * `auto p = make_shared<double[1024]>(1.0);` | ||||
| * `auto p = make_shared<double[6][2]>({1.0, 0.0});` | ||||
| * `auto p = make_shared<std::vector<int>[4]>({1, 2});` | ||||
| @@ -266,30 +266,31 @@ Examples::: | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared_noinit(); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared_noinit(const A& a); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type, or an array type of the `U[N]`. | ||||
| Returns::: A `shared_ptr` to a default-initialized object of type `T`, or a | ||||
| sequence of `N` default-initialized objects of type `U`, respectively. | ||||
| Example::: `auto p = make_shared_noinit<double[1024]>();` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array, or is an array of known bounds. | ||||
| Returns:: A `shared_ptr` to a default-initialized object of type `T`, or a | ||||
| sequence of `extent_v<T>` default-initialized objects of type | ||||
| `remove_extent_t<T>`, respectively. | ||||
| Example:: `auto p = make_shared_noinit<double[1024]>();` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared_noinit(std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `_n_` default-initialized objects | ||||
| of type `U`. | ||||
| Example::: `auto p = make_shared_noinit<double[]>(1024);` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `_n_` default-initialized objects | ||||
| of type `remove_extent_t<T>`. | ||||
| Example:: `auto p = make_shared_noinit<double[]>(1024);` | ||||
|   | ||||
| @@ -30,33 +30,33 @@ requests from users. | ||||
|  | ||||
| This library also provides additional overloads of `make_unique` for | ||||
| default-initialization, when users do not need or want to incur the expense | ||||
| of value-initialization. The {cpp} standard does not yet provide this | ||||
| feature with `std::make_unique`. | ||||
| of value-initialization. The {cpp}20 standard now provides this feature with | ||||
| `std::make_unique_for_overwrite`. | ||||
|  | ||||
| ## Synopsis | ||||
|  | ||||
| `make_unique` is defined in `<boost/smart_ptr/make_unqiue.hpp>`. | ||||
| `make_unique` is defined in `<boost/smart_ptr/make_unique.hpp>`. | ||||
|  | ||||
| [subs=+quotes] | ||||
| ``` | ||||
| namespace boost { | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T, class... Args> | ||||
|     std::unique_ptr<T> make_unique(Args&&... args); | ||||
|  | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T> | ||||
|     std::unique_ptr<T> make_unique(remove_reference_t<T>&& v); | ||||
|     std::unique_ptr<T> make_unique(type_identity_t<T>&& v); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     std::unique_ptr<T> make_unique(std::size_t n); | ||||
|  | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T> | ||||
|     std::unique_ptr<T> make_unique_noinit(); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     std::unique_ptr<T> make_unique_noinit(std::size_t n); | ||||
| } | ||||
| @@ -68,48 +68,53 @@ namespace boost { | ||||
| template<class T, class... Args> | ||||
|   std::unique_ptr<T> make_unique(Args&&... args); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type. | ||||
| Returns::: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`. | ||||
| Example::: `auto p = make_unique<int>();` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`. | ||||
| Example:: `auto p = make_unique<int>();` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   std::unique_ptr<T> make_unique(remove_reference_t<T>&& v); | ||||
|   std::unique_ptr<T> make_unique(type_identity_t<T>&& v); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type. | ||||
| Returns::: `std::unique_ptr<T>(new T(std::move(v))`. | ||||
| Example::: `auto p = make_unique<std::vector<int> >({1, 2});` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: `std::unique_ptr<T>(new T(std::move(v))`. | ||||
| Example:: `auto p = make_unique<std::vector<int> >({1, 2});` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   std::unique_ptr<T> make_unique(std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: `std::unique_ptr<U[]>(new U[n]())`. | ||||
| Example::: `auto p = make_unique<double[]>(1024);` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: `std::unique_ptr<T>(new remove_extent_t<T>[n]())`. | ||||
| Example:: `auto p = make_unique<double[]>(1024);` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   std::unique_ptr<T> make_unique_noinit(); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type. | ||||
| Returns::: `std::unique_ptr<T>(new T)`. | ||||
| Example::: `auto p = make_unique_noinit<double[1024]>();` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: `std::unique_ptr<T>(new T)`. | ||||
| Example:: `auto p = make_unique_noinit<std::array<double, 1024> >();` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   std::unique_ptr<T> make_unique_noinit(std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: `std::unique_ptr<U[]>(new U[n])`. | ||||
| Example::: `auto p = make_unique_noinit<double[]>(1024);` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: `std::unique_ptr<T>(new remove_extent_t<T>[n])`. | ||||
| Example:: `auto p = make_unique_noinit<double[]>(1024);` | ||||
|   | ||||
							
								
								
									
										45
									
								
								doc/smart_ptr/owner_equal_to.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								doc/smart_ptr/owner_equal_to.adoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| //// | ||||
| Copyright 2020 Peter Dimov | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| https://www.boost.org/LICENSE_1_0.txt | ||||
| //// | ||||
|  | ||||
| [#owner_equal_to] | ||||
| # owner_equal_to | ||||
| :toc: | ||||
| :toc-title: | ||||
| :idprefix: owner_equal_to_ | ||||
|  | ||||
| ## Description | ||||
|  | ||||
| `owner_equal_to<T>` is a helper function object that compares two smart | ||||
| pointer objects using `owner_equals`. | ||||
|  | ||||
| ## Synopsis | ||||
|  | ||||
| `owner_equal_to` is defined in `<boost/smart_ptr/owner_equal_to.hpp>`. | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
|  | ||||
|   template<class T = void> struct owner_equal_to | ||||
|   { | ||||
|     typedef bool result_type; | ||||
|     typedef T first_argument_type; | ||||
|     typedef T second_argument_type; | ||||
|  | ||||
|     template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept; | ||||
|   }; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Members | ||||
|  | ||||
| ``` | ||||
| template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   `u.owner_equals( v )`. | ||||
							
								
								
									
										56
									
								
								doc/smart_ptr/owner_hash.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								doc/smart_ptr/owner_hash.adoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| //// | ||||
| Copyright 2020 Peter Dimov | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| https://www.boost.org/LICENSE_1_0.txt | ||||
| //// | ||||
|  | ||||
| [#owner_hash] | ||||
| # owner_hash | ||||
| :toc: | ||||
| :toc-title: | ||||
| :idprefix: owner_hash_to_ | ||||
|  | ||||
| ## Description | ||||
|  | ||||
| `owner_hash<T>` is a helper function object that takes a smart pointer `p` | ||||
| and returns `p.owner_hash_value()`. It's useful for creating unordered | ||||
| containers of `shared_ptr` that use ownership-based equality, instead of | ||||
| the default pointer value equality. (It can be used with `weak_ptr` too, | ||||
| but there's no need, because `boost::hash` and `std::hash` for `weak_ptr` | ||||
| already use ownership-based equality.) | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ``` | ||||
| std::unordered_set< boost::shared_ptr<void>, | ||||
|   boost::owner_hash< boost::shared_ptr<void> >, | ||||
|   boost::owner_equal_to< boost::shared_ptr<void> > > set; | ||||
| ``` | ||||
|  | ||||
| ## Synopsis | ||||
|  | ||||
| `owner_hash` is defined in `<boost/smart_ptr/owner_hash.hpp>`. | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
|  | ||||
|   template<class T> struct owner_hash | ||||
|   { | ||||
|     typedef std::size_t result_type; | ||||
|     typedef T argument_type; | ||||
|  | ||||
|     std::size_t operator()( T const & p ) const noexcept; | ||||
|   }; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Members | ||||
|  | ||||
| ``` | ||||
| std::size_t operator()( T const & p ) const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   `p.owner_hash_value()`. | ||||
							
								
								
									
										50
									
								
								doc/smart_ptr/owner_less.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								doc/smart_ptr/owner_less.adoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| //// | ||||
| Copyright 2020 Peter Dimov | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| https://www.boost.org/LICENSE_1_0.txt | ||||
| //// | ||||
|  | ||||
| [#owner_less] | ||||
| # owner_less | ||||
| :toc: | ||||
| :toc-title: | ||||
| :idprefix: owner_less_ | ||||
|  | ||||
| ## Description | ||||
|  | ||||
| `owner_less<T>` is a helper function object that compares two smart | ||||
| pointer objects using `owner_before`. It is only provided for compatibility | ||||
| with {cpp}11 and corresponds to the standard component of the same name. | ||||
|  | ||||
| When using Boost smart pointers, the use of `owner_less` is unnecessary, as | ||||
| the supplied `operator<` overloads (and, correspondingly, `std::less`) return | ||||
| the same result. | ||||
|  | ||||
| ## Synopsis | ||||
|  | ||||
| `owner_less` is defined in `<boost/smart_ptr/owner_less.hpp>`. | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
|  | ||||
|   template<class T = void> struct owner_less | ||||
|   { | ||||
|     typedef bool result_type; | ||||
|     typedef T first_argument_type; | ||||
|     typedef T second_argument_type; | ||||
|  | ||||
|     template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept; | ||||
|   }; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Members | ||||
|  | ||||
| ``` | ||||
| template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   `u.owner_before( v )`. | ||||
| @@ -78,23 +78,29 @@ namespace boost { | ||||
| ``` | ||||
| template<class T, class U> T* static_pointer_cast(U* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `static_cast<T*>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `static_cast<T*>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::shared_ptr<T> | ||||
|   static_pointer_cast(const std::shared_ptr<U>& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `std::static_pointer_cast<T>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `std::static_pointer_cast<T>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::unique_ptr<T> | ||||
|   static_pointer_cast(std::unique_ptr<U>&& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Requires::: The expression `static_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns::: `std::unique_ptr<T>(static_cast<typename | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Requires:: The expression `static_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns:: `std::unique_ptr<T>(static_cast<typename | ||||
| std::unique_ptr<T>::element_type*>(p.release()))`. | ||||
|  | ||||
| CAUTION: The seemingly equivalent expression | ||||
| @@ -106,25 +112,31 @@ undefined behavior, attempting to delete the same object twice. | ||||
| ``` | ||||
| template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `dynamic_cast<T*>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `dynamic_cast<T*>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::shared_ptr<T> | ||||
|   dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `std::dynamic_pointer_cast<T>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `std::dynamic_pointer_cast<T>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::unique_ptr<T> | ||||
|   dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Requires::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Requires:: | ||||
| * The expression `static_cast<T*>((U*)0)` must be well-formed. | ||||
| * `T` must have a virtual destructor. | ||||
| Returns::: | ||||
| Returns:: | ||||
| * When `dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.get())` | ||||
| returns a non-zero value, `std::unique_ptr<T>(dynamic_cast<typename | ||||
| std::unique_ptr<T>::element_type*>(p.release()));`. | ||||
| @@ -135,23 +147,29 @@ std::unique_ptr<T>::element_type*>(p.release()));`. | ||||
| ``` | ||||
| template<class T, class U> T* const_pointer_cast(U* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `const_cast<T*>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `const_cast<T*>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::shared_ptr<T> | ||||
|   const_pointer_cast(const std::shared_ptr<U>& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `std::const_pointer_cast<T>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `std::const_pointer_cast<T>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::unique_ptr<T> | ||||
|   const_pointer_cast(std::unique_ptr<U>&& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Requires::: The expression `const_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns::: `std::unique_ptr<T>(const_cast<typename | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Requires:: The expression `const_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns:: `std::unique_ptr<T>(const_cast<typename | ||||
| std::unique_ptr<T>::element_type*>(p.release()))`. | ||||
|  | ||||
| ### reinterpret_pointer_cast | ||||
| @@ -159,23 +177,29 @@ std::unique_ptr<T>::element_type*>(p.release()))`. | ||||
| ``` | ||||
| template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `reinterpret_cast<T*>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `reinterpret_cast<T*>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::shared_ptr<T> | ||||
|   reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `std::reinterpret_pointer_cast<T>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `std::reinterpret_pointer_cast<T>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::unique_ptr<T> | ||||
|   reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Requires::: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns::: `std::unique_ptr<T>(reinterpret_cast<typename | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Requires:: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns:: `std::unique_ptr<T>(reinterpret_cast<typename | ||||
| std::unique_ptr<T>::element_type*>(p.release()))`. | ||||
|  | ||||
| ## Example | ||||
| @@ -210,4 +234,4 @@ int main() | ||||
|  | ||||
|   delete ptr; | ||||
| } | ||||
| ``` | ||||
| ``` | ||||
|   | ||||
| @@ -105,42 +105,50 @@ Type:: Provides the type of the stored pointer. | ||||
| ``` | ||||
| explicit shared_array(T* p = 0); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a `shared_array`, storing a copy of `p`, which must be a | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a `shared_array`, storing a copy of `p`, which must be a | ||||
| pointer to an array that was allocated via a C++ `new[]` expression or be 0. | ||||
| Afterwards, the use count is 1 (even if `p == 0`; see `~shared_array`). | ||||
| Requires::: `T` is a complete type. | ||||
| Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. | ||||
| Requires:: `T` is a complete type. | ||||
| Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. | ||||
|  | ||||
| ``` | ||||
| template<class D> shared_array(T* p, D d); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a `shared_array`, storing a copy of `p` and of `d`. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a `shared_array`, storing a copy of `p` and of `d`. | ||||
| Afterwards, the use count is 1. When the the time comes to delete the array | ||||
| pointed to by `p`, the object `d` is used in the statement `d(p)`. | ||||
| Requires::: | ||||
| Requires:: | ||||
| * `T` is a complete type. | ||||
| * The copy constructor and destructor of `D` must not throw. | ||||
| * Invoking the object `d` with parameter `p` must not throw. | ||||
| Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. | ||||
| Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. | ||||
|  | ||||
| ``` | ||||
| shared_array(const shared_array& v) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a `shared_array`, as if by storing a copy of the pointer | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a `shared_array`, as if by storing a copy of the pointer | ||||
| stored in `v`. Afterwards, the use count for all copies is 1 more than the | ||||
| initial use count. | ||||
| Requires::: `T` is a complete type. | ||||
| Requires:: `T` is a complete type. | ||||
|  | ||||
| ### Destructor | ||||
|  | ||||
| ``` | ||||
| ~shared_array() noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Decrements the use count. Then, if the use count is 0, deletes the | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Decrements the use count. Then, if the use count is 0, deletes the | ||||
| array pointed to by the stored pointer. Note that `delete[]` on a pointer with | ||||
| a value of 0 is harmless.  | ||||
|  | ||||
| @@ -149,69 +157,82 @@ a value of 0 is harmless. | ||||
| ``` | ||||
| shared_array& operator=(const shared_array& v) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a new `shared_array` as described above, then replaces | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a new `shared_array` as described above, then replaces | ||||
| this `shared_array` with the new one, destroying the replaced object. | ||||
| Requires::: `T` is a complete type. | ||||
| Returns::: `*this`. | ||||
| Requires:: `T` is a complete type. | ||||
| Returns:: `*this`. | ||||
|  | ||||
| ### reset | ||||
|  | ||||
| ``` | ||||
| void reset(T* p = 0); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a new `shared_array` as described above, then replaces | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a new `shared_array` as described above, then replaces | ||||
| this `shared_array` with the new one, destroying the replaced object. | ||||
| Requires::: `T` is a complete type. | ||||
| Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. | ||||
| Requires:: `T` is a complete type. | ||||
| Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. | ||||
|  | ||||
| ``` | ||||
| template<class D> void reset(T* p, D d); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a new `shared_array` as described above, then replaces | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a new `shared_array` as described above, then replaces | ||||
| this `shared_array` with the new one, destroying the replaced object. | ||||
| Requires::: | ||||
| Requires:: | ||||
| * `T` is a complete type. | ||||
| * The copy constructor of `D` must not throw. | ||||
| Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. | ||||
| Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. | ||||
|  | ||||
| ### Indexing | ||||
|  | ||||
| ``` | ||||
| T& operator[](std::ptrdiff_t n) const noexcept; | ||||
| ``` | ||||
| Returns::: A reference to element `n` of the array pointed to by the stored | ||||
| Returns:: A reference to element `n` of the array pointed to by the stored | ||||
| pointer. Behavior is undefined and almost certainly undesirable if the stored | ||||
| pointer is 0, or if `n` is less than 0 or is greater than or equal to the | ||||
| number of elements in the array. | ||||
| Requires::: `T` is a complete type. | ||||
| Requires:: `T` is a complete type. | ||||
|  | ||||
| ### get | ||||
|  | ||||
| ``` | ||||
| T* get() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: The stored pointer. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   The stored pointer. | ||||
|  | ||||
| ### unique | ||||
|  | ||||
| ``` | ||||
| bool unique() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `true` if no other `shared_array` is sharing ownership of the | ||||
| stored pointer, `false` otherwise. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   `true` if no other `shared_array` is sharing ownership of the stored pointer, `false` otherwise. | ||||
|  | ||||
| ### use_count | ||||
|  | ||||
| ``` | ||||
| long use_count() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: The number of `shared_array` objects sharing ownership of the | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The number of `shared_array` objects sharing ownership of the | ||||
| stored pointer. | ||||
|  | ||||
| ### Conversions | ||||
| @@ -219,17 +240,22 @@ stored pointer. | ||||
| ``` | ||||
| explicit operator bool() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `get() != 0`. | ||||
| Requires::: `T` is a complete type. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `get() != 0`. | ||||
| Requires:: `T` is a complete type. | ||||
|  | ||||
| ### swap | ||||
|  | ||||
| ``` | ||||
| void swap(shared_array<T>& b) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Exchanges the contents of the two smart pointers. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: | ||||
|   Exchanges the contents of the two smart pointers. | ||||
|  | ||||
| ## Free Functions | ||||
|  | ||||
| @@ -247,8 +273,10 @@ template<class T> bool | ||||
| template<class T> bool | ||||
|   operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: The result of comparing the stored pointers of the two smart | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The result of comparing the stored pointers of the two smart | ||||
| pointers. | ||||
|  | ||||
| NOTE: The `operator<` overload is provided to define an ordering so that | ||||
| @@ -265,6 +293,8 @@ mandates that relational operations on pointers are unspecified (5.9 | ||||
| template<class T> | ||||
|   void swap(shared_array<T>& a, shared_array<T>& b) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `a.swap(b)`. | ||||
| Requires::: `T` is a complete type. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `a.swap(b)`. | ||||
| Requires:: `T` is a complete type. | ||||
|   | ||||
| @@ -132,7 +132,6 @@ namespace boost { | ||||
|     template<class Y> shared_ptr(shared_ptr<Y> && r) noexcept; | ||||
|  | ||||
|     template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p) noexcept; | ||||
|  | ||||
|     template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p) noexcept; | ||||
|  | ||||
|     template<class Y> explicit shared_ptr(weak_ptr<Y> const & r); | ||||
| @@ -179,8 +178,13 @@ namespace boost { | ||||
|  | ||||
|     void swap(shared_ptr & b) noexcept; | ||||
|  | ||||
|     template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept; | ||||
|     template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept; | ||||
|     template<class Y> bool owner_before(shared_ptr<Y> const & r) const noexcept; | ||||
|     template<class Y> bool owner_before(weak_ptr<Y> const & r) const noexcept; | ||||
|  | ||||
|     template<class Y> bool owner_equals(shared_ptr<Y> const & r) const noexcept; | ||||
|     template<class Y> bool owner_equals(weak_ptr<Y> const & r) const noexcept; | ||||
|  | ||||
|     std::size_t owner_hash_value() const noexcept; | ||||
|   }; | ||||
|  | ||||
|   template<class T, class U> | ||||
| @@ -373,7 +377,7 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p) noexcept | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: constructs a `shared_ptr` that shares ownership with `r` and stores `p`. | ||||
| Effects:: Copy-constructs a `shared_ptr` from `r`, while storing `p` instead. | ||||
|  | ||||
| Postconditions:: `get() == p && use_count() == r.use_count()`. | ||||
|  | ||||
| @@ -561,7 +565,8 @@ template<class Y> void reset(shared_ptr<Y> && r, element_type * p) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `shared_ptr(std::move(r), p).swap(*this)`. | ||||
| Effects:: | ||||
|   Equivalent to `shared_ptr(std::move(r), p).swap(*this)`. | ||||
|  | ||||
| ### indirection | ||||
| ``` | ||||
| @@ -599,7 +604,8 @@ element_type * get() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The stored pointer. | ||||
| Returns:: | ||||
|   The stored pointer. | ||||
|  | ||||
| ### unique | ||||
| ``` | ||||
| @@ -608,7 +614,8 @@ bool unique() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `use_count() == 1`. | ||||
| Returns:: | ||||
|   `use_count() == 1`. | ||||
|  | ||||
| ### use_count | ||||
| ``` | ||||
| @@ -617,7 +624,8 @@ long use_count() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The number of `shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty. | ||||
| Returns:: | ||||
|   The number of `shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty. | ||||
|  | ||||
| ### conversions | ||||
| ``` | ||||
| @@ -642,19 +650,45 @@ void swap(shared_ptr & b) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Exchanges the contents of the two smart pointers. | ||||
| Effects:: | ||||
|   Exchanges the contents of the two smart pointers. | ||||
|  | ||||
| ### owner_before | ||||
| ``` | ||||
| template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept; | ||||
| template<class Y> bool owner_before(shared_ptr<Y> const & r) const noexcept; | ||||
| ``` | ||||
| ``` | ||||
| template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept; | ||||
| template<class Y> bool owner_before(weak_ptr<Y> const & r) const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: See the description of `operator<`. | ||||
| Returns:: | ||||
|   See the description of `operator<`. | ||||
|  | ||||
| ### owner_equals | ||||
| ``` | ||||
| template<class Y> bool owner_equals(shared_ptr<Y> const & r) const noexcept; | ||||
| ``` | ||||
| ``` | ||||
| template<class Y> bool owner_equals(weak_ptr<Y> const & r) const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   `true` if and only if `*this` and `r` share ownership or are both empty. | ||||
|  | ||||
| ### owner_hash_value | ||||
| ``` | ||||
| std::size_t owner_hash_value() const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   An unspecified hash value such that two instances that share ownership | ||||
|   have the same hash value. | ||||
|  | ||||
| ## Free Functions | ||||
|  | ||||
| @@ -722,7 +756,8 @@ template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `a.swap(b)`. | ||||
| Effects:: | ||||
|   Equivalent to `a.swap(b)`. | ||||
|  | ||||
| ### get_pointer | ||||
| ``` | ||||
| @@ -806,7 +841,8 @@ template<class D, class T> | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: If `*this` owns a deleter `d` of type (cv-unqualified) `D`, returns `&d`; otherwise returns 0. | ||||
| Returns:: | ||||
|   If `*this` owns a deleter `d` of type (cv-unqualified) `D`, returns `&d`; otherwise returns 0. | ||||
|  | ||||
| ### Atomic Access | ||||
|  | ||||
|   | ||||
| @@ -88,6 +88,10 @@ namespace boost { | ||||
|  | ||||
|     weak_ptr(weak_ptr && r) noexcept; | ||||
|  | ||||
|     template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) noexcept; | ||||
|     template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) noexcept; | ||||
|     template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) noexcept; | ||||
|  | ||||
|     ~weak_ptr() noexcept; | ||||
|  | ||||
|     weak_ptr & operator=(weak_ptr const & r) noexcept; | ||||
| @@ -98,6 +102,8 @@ namespace boost { | ||||
|     long use_count() const noexcept; | ||||
|     bool expired() const noexcept; | ||||
|  | ||||
|     bool empty() const noexcept; | ||||
|  | ||||
|     shared_ptr<T> lock() const noexcept; | ||||
|  | ||||
|     void reset() noexcept; | ||||
| @@ -106,6 +112,11 @@ namespace boost { | ||||
|  | ||||
|     template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept; | ||||
|     template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept; | ||||
|  | ||||
|     template<class Y> bool owner_equals( weak_ptr<Y> const & r ) const noexcept; | ||||
|     template<class Y> bool owner_equals( shared_ptr<Y> const & r ) const noexcept; | ||||
|  | ||||
|     std::size_t owner_hash_value() const noexcept; | ||||
|   }; | ||||
|  | ||||
|   template<class T, class U> | ||||
| @@ -157,6 +168,21 @@ weak_ptr(weak_ptr && r) noexcept; | ||||
| Effects:: Constructs a `weak_ptr` that has the value `r` held. | ||||
| Postconditions:: `r` is empty. | ||||
|  | ||||
| ### aliasing constructors | ||||
| ``` | ||||
| template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) noexcept; | ||||
| ``` | ||||
| ``` | ||||
| template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) noexcept; | ||||
| ``` | ||||
| ``` | ||||
| template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) noexcept; | ||||
| ``` | ||||
| Effects:: Constructs a `weak_ptr` from `r` as if by using the corresponding converting/copy/move constructor, but stores `p` instead. | ||||
| Postconditions:: `use_count() == r.use_count()`. When `!expired()`, `shared_ptr<T>(*this).get() == p`. | ||||
|  | ||||
| NOTE: These constructors are an extension, not present in `std::weak_ptr`. | ||||
|  | ||||
| ### destructor | ||||
| ``` | ||||
| ~weak_ptr() noexcept; | ||||
| @@ -164,7 +190,8 @@ Postconditions:: `r` is empty. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Destroys this `weak_ptr` but has no effect on the object its stored pointer points to. | ||||
| Effects:: | ||||
|   Destroys this `weak_ptr` but has no effect on the object its stored pointer points to. | ||||
|  | ||||
| ### assignment | ||||
| ``` | ||||
| @@ -193,7 +220,8 @@ long use_count() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: 0 if `*this` is empty; otherwise, the number of `shared_ptr` objects that share ownership with `*this`. | ||||
| Returns:: | ||||
|   0 if `*this` is empty; otherwise, the number of `shared_ptr` objects that share ownership with `*this`. | ||||
|  | ||||
| ### expired | ||||
| ``` | ||||
| @@ -202,7 +230,19 @@ bool expired() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `use_count() == 0`. | ||||
| Returns:: | ||||
|   `use_count() == 0`. | ||||
|  | ||||
| ### empty | ||||
| ``` | ||||
| bool empty() const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `true` when `*this` is empty, `false` otherwise. | ||||
|  | ||||
| NOTE: This function is an extension, not present in `std::weak_ptr`. | ||||
|  | ||||
| ### lock | ||||
| ``` | ||||
| @@ -211,7 +251,8 @@ shared_ptr<T> lock() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `expired()? shared_ptr<T>(): shared_ptr<T>(*this)`. | ||||
| Returns:: | ||||
|   `expired()? shared_ptr<T>(): shared_ptr<T>(*this)`. | ||||
|  | ||||
| ### reset | ||||
| ``` | ||||
| @@ -220,7 +261,8 @@ void reset() noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `weak_ptr().swap(*this)`. | ||||
| Effects:: | ||||
|   Equivalent to `weak_ptr().swap(*this)`. | ||||
|  | ||||
| ### swap | ||||
| ``` | ||||
| @@ -229,8 +271,10 @@ void swap(weak_ptr & b) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Exchanges the contents of the two smart pointers. | ||||
| Effects:: | ||||
|   Exchanges the contents of the two smart pointers. | ||||
|  | ||||
| ### owner_before | ||||
| ``` | ||||
| template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept; | ||||
| ``` | ||||
| @@ -240,7 +284,32 @@ template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: See the description of `operator<`. | ||||
| Returns:: | ||||
|   See the description of `operator<`. | ||||
|  | ||||
| ### owner_equals | ||||
| ``` | ||||
| template<class Y> bool owner_equals( weak_ptr<Y> const & r ) const noexcept; | ||||
| ``` | ||||
| ``` | ||||
| template<class Y> bool owner_equals( shared_ptr<Y> const & r ) const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   `true` if and only if `*this` and `r` share ownership or are both empty. | ||||
|  | ||||
| ### owner_hash_value | ||||
| ``` | ||||
| std::size_t owner_hash_value() const noexcept; | ||||
| ``` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: | ||||
|   An unspecified hash value such that two instances that share ownership | ||||
|   have the same hash value. | ||||
|  | ||||
| ## Free Functions | ||||
|  | ||||
| @@ -266,7 +335,8 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `a.swap(b)`. | ||||
| Effects:: | ||||
|   Equivalent to `a.swap(b)`. | ||||
|  | ||||
| ## Frequently Asked Questions | ||||
|  | ||||
|   | ||||
| @@ -1,270 +0,0 @@ | ||||
| // | ||||
| //  sp_collector.cpp | ||||
| // | ||||
| //  Copyright (c) 2002, 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) | ||||
| // | ||||
|  | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|  | ||||
| #include <boost/assert.hpp> | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/detail/lightweight_mutex.hpp> | ||||
| #include <cstdlib> | ||||
| #include <map> | ||||
| #include <deque> | ||||
| #include <iostream> | ||||
|  | ||||
| typedef std::map< void const *, std::pair<void *, size_t> > map_type; | ||||
|  | ||||
| static map_type & get_map() | ||||
| { | ||||
|     static map_type m; | ||||
|     return m; | ||||
| } | ||||
|  | ||||
| typedef boost::detail::lightweight_mutex mutex_type; | ||||
|  | ||||
| static mutex_type & get_mutex() | ||||
| { | ||||
|     static mutex_type m; | ||||
|     return m; | ||||
| } | ||||
|  | ||||
| static void * init_mutex_before_main = &get_mutex(); | ||||
|  | ||||
| namespace | ||||
| { | ||||
|     class X; | ||||
|  | ||||
|     struct count_layout | ||||
|     { | ||||
|         boost::detail::sp_counted_base * pi; | ||||
|         int id; | ||||
|     }; | ||||
|  | ||||
|     struct shared_ptr_layout | ||||
|     { | ||||
|         X * px; | ||||
|         count_layout pn; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| // assume 4 byte alignment for pointers when scanning | ||||
| size_t const pointer_align = 4; | ||||
|  | ||||
| typedef std::map<void const *, long> map2_type; | ||||
|  | ||||
| static void scan_and_count(void const * area, size_t size, map_type const & m, map2_type & m2) | ||||
| { | ||||
|     unsigned char const * p = static_cast<unsigned char const *>(area); | ||||
|  | ||||
|     for(size_t n = 0; n + sizeof(shared_ptr_layout) <= size; p += pointer_align, n += pointer_align) | ||||
|     { | ||||
|         shared_ptr_layout const * q = reinterpret_cast<shared_ptr_layout const *>(p); | ||||
|  | ||||
|         if(q->pn.id == boost::detail::shared_count_id && q->pn.pi != 0 && m.count(q->pn.pi) != 0) | ||||
|         { | ||||
|             ++m2[q->pn.pi]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| typedef std::deque<void const *> open_type; | ||||
|  | ||||
| static void scan_and_mark(void const * area, size_t size, map2_type & m2, open_type & open) | ||||
| { | ||||
|     unsigned char const * p = static_cast<unsigned char const *>(area); | ||||
|  | ||||
|     for(size_t n = 0; n + sizeof(shared_ptr_layout) <= size; p += pointer_align, n += pointer_align) | ||||
|     { | ||||
|         shared_ptr_layout const * q = reinterpret_cast<shared_ptr_layout const *>(p); | ||||
|  | ||||
|         if(q->pn.id == boost::detail::shared_count_id && q->pn.pi != 0 && m2.count(q->pn.pi) != 0) | ||||
|         { | ||||
|             open.push_back(q->pn.pi); | ||||
|             m2.erase(q->pn.pi); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void find_unreachable_objects_impl(map_type const & m, map2_type & m2) | ||||
| { | ||||
|     // scan objects for shared_ptr members, compute internal counts | ||||
|  | ||||
|     { | ||||
|         std::cout << "... " << m.size() << " objects in m.\n"; | ||||
|  | ||||
|         for(map_type::const_iterator i = m.begin(); i != m.end(); ++i) | ||||
|         { | ||||
|             boost::detail::sp_counted_base const * p = static_cast<boost::detail::sp_counted_base const *>(i->first); | ||||
|  | ||||
|             BOOST_ASSERT(p->use_count() != 0); // there should be no inactive counts in the map | ||||
|  | ||||
|             m2[ i->first ]; | ||||
|  | ||||
|             scan_and_count(i->second.first, i->second.second, m, m2); | ||||
|         } | ||||
|  | ||||
|         std::cout << "... " << m2.size() << " objects in m2.\n"; | ||||
|     } | ||||
|  | ||||
|     // mark reachable objects | ||||
|  | ||||
|     { | ||||
|         open_type open; | ||||
|  | ||||
|         for(map2_type::iterator i = m2.begin(); i != m2.end(); ++i) | ||||
|         { | ||||
|             boost::detail::sp_counted_base const * p = static_cast<boost::detail::sp_counted_base const *>(i->first); | ||||
|             if(p->use_count() != i->second) open.push_back(p); | ||||
|         } | ||||
|  | ||||
|         std::cout << "... " << open.size() << " objects in open.\n"; | ||||
|  | ||||
|         for(open_type::iterator j = open.begin(); j != open.end(); ++j) | ||||
|         { | ||||
|             m2.erase(*j); | ||||
|         } | ||||
|  | ||||
|         while(!open.empty()) | ||||
|         { | ||||
|             void const * p = open.front(); | ||||
|             open.pop_front(); | ||||
|  | ||||
|             map_type::const_iterator i = m.find(p); | ||||
|             BOOST_ASSERT(i != m.end()); | ||||
|  | ||||
|             scan_and_mark(i->second.first, i->second.second, m2, open); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // m2 now contains the unreachable objects | ||||
| } | ||||
|  | ||||
| std::size_t find_unreachable_objects(bool report) | ||||
| { | ||||
|     map2_type m2; | ||||
|  | ||||
| #ifdef BOOST_HAS_THREADS | ||||
|  | ||||
|     // This will work without the #ifdef, but some compilers warn | ||||
|     // that lock is not referenced | ||||
|  | ||||
|     mutex_type::scoped_lock lock(get_mutex()); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     map_type const & m = get_map(); | ||||
|  | ||||
|     find_unreachable_objects_impl(m, m2); | ||||
|  | ||||
|     if(report) | ||||
|     { | ||||
|         for(map2_type::iterator j = m2.begin(); j != m2.end(); ++j) | ||||
|         { | ||||
|             map_type::const_iterator i = m.find(j->first); | ||||
|             BOOST_ASSERT(i != m.end()); | ||||
|             std::cout << "Unreachable object at " << i->second.first << ", " << i->second.second << " bytes long.\n"; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return m2.size(); | ||||
| } | ||||
|  | ||||
| typedef std::deque< boost::shared_ptr<X> > free_list_type; | ||||
|  | ||||
| static void scan_and_free(void * area, size_t size, map2_type const & m2, free_list_type & free) | ||||
| { | ||||
|     unsigned char * p = static_cast<unsigned char *>(area); | ||||
|  | ||||
|     for(size_t n = 0; n + sizeof(shared_ptr_layout) <= size; p += pointer_align, n += pointer_align) | ||||
|     { | ||||
|         shared_ptr_layout * q = reinterpret_cast<shared_ptr_layout *>(p); | ||||
|  | ||||
|         if(q->pn.id == boost::detail::shared_count_id && q->pn.pi != 0 && m2.count(q->pn.pi) != 0 && q->px != 0) | ||||
|         { | ||||
|             boost::shared_ptr<X> * ppx = reinterpret_cast< boost::shared_ptr<X> * >(p); | ||||
|             free.push_back(*ppx); | ||||
|             ppx->reset(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void free_unreachable_objects() | ||||
| { | ||||
|     free_list_type free; | ||||
|  | ||||
|     { | ||||
|         map2_type m2; | ||||
|  | ||||
| #ifdef BOOST_HAS_THREADS | ||||
|  | ||||
|         mutex_type::scoped_lock lock(get_mutex()); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|         map_type const & m = get_map(); | ||||
|  | ||||
|         find_unreachable_objects_impl(m, m2); | ||||
|  | ||||
|         for(map2_type::iterator j = m2.begin(); j != m2.end(); ++j) | ||||
|         { | ||||
|             map_type::const_iterator i = m.find(j->first); | ||||
|             BOOST_ASSERT(i != m.end()); | ||||
|             scan_and_free(i->second.first, i->second.second, m2, free); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     std::cout << "... about to free " << free.size() << " objects.\n"; | ||||
| } | ||||
|  | ||||
| // debug hooks | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| void sp_scalar_constructor_hook(void *) | ||||
| { | ||||
| } | ||||
|  | ||||
| void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn) | ||||
| { | ||||
| #ifdef BOOST_HAS_THREADS | ||||
|  | ||||
|     mutex_type::scoped_lock lock(get_mutex()); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     get_map()[pn] = std::make_pair(px, size); | ||||
| } | ||||
|  | ||||
| void sp_scalar_destructor_hook(void *) | ||||
| { | ||||
| } | ||||
|  | ||||
| void sp_scalar_destructor_hook(void *, std::size_t, void * pn) | ||||
| { | ||||
| #ifdef BOOST_HAS_THREADS | ||||
|  | ||||
|     mutex_type::scoped_lock lock(get_mutex()); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     get_map().erase(pn); | ||||
| } | ||||
|  | ||||
| void sp_array_constructor_hook(void *) | ||||
| { | ||||
| } | ||||
|  | ||||
| void sp_array_destructor_hook(void *) | ||||
| { | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
| @@ -1,243 +0,0 @@ | ||||
| // | ||||
| //  sp_debug_hooks.cpp | ||||
| // | ||||
| //  Copyright (c) 2002, 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) | ||||
| // | ||||
|  | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|  | ||||
| #include <boost/assert.hpp> | ||||
| #include <new> | ||||
| #include <cstdlib> | ||||
|  | ||||
| int const m = 2; // m * sizeof(int) must be aligned appropriately | ||||
|  | ||||
| // magic values to mark heap blocks with | ||||
|  | ||||
| int const allocated_scalar  = 0x1234560C; | ||||
| int const allocated_array   = 0x1234560A; | ||||
| int const adopted_scalar    = 0x0567890C; | ||||
| int const adopted_array     = 0x0567890A; | ||||
| int const deleted           = 0x498769DE; | ||||
|  | ||||
| using namespace std; // for compilers where things aren't in std | ||||
|  | ||||
| // operator new | ||||
|  | ||||
| static new_handler get_new_handler() | ||||
| { | ||||
|     new_handler p = set_new_handler(0); | ||||
|     set_new_handler(p); | ||||
|     return p; | ||||
| } | ||||
|  | ||||
| static void * allocate(size_t n, int mark) | ||||
| { | ||||
|     int * pm; | ||||
|  | ||||
|     for(;;) | ||||
|     { | ||||
|         pm = static_cast<int*>(malloc(n + m * sizeof(int))); | ||||
|  | ||||
|         if(pm != 0) break; | ||||
|  | ||||
|         if(new_handler pnh = get_new_handler()) | ||||
|         { | ||||
|             pnh(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     *pm = mark; | ||||
|  | ||||
|     return pm + m; | ||||
| } | ||||
|  | ||||
| void * operator new(size_t n) throw(bad_alloc) | ||||
| { | ||||
|     void * p = allocate(n, allocated_scalar); | ||||
|  | ||||
| #if !defined(BOOST_NO_EXCEPTIONS) | ||||
|  | ||||
|     if(p == 0) throw bad_alloc(); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     return p; | ||||
| } | ||||
|  | ||||
| #if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551) | ||||
|  | ||||
| void * operator new(size_t n, nothrow_t const &) throw() | ||||
| { | ||||
|     return allocate(n, allocated_scalar); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| void * operator new[](size_t n) throw(bad_alloc) | ||||
| { | ||||
|     void * p = allocate(n, allocated_array); | ||||
|  | ||||
| #if !defined(BOOST_NO_EXCEPTIONS) | ||||
|  | ||||
|     if(p == 0) throw bad_alloc(); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     return p; | ||||
| } | ||||
|  | ||||
| #if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551) | ||||
|  | ||||
| void * operator new[](size_t n, nothrow_t const &) throw() | ||||
| { | ||||
|     return allocate(n, allocated_array); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // debug hooks | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| void sp_scalar_constructor_hook(void * p) | ||||
| { | ||||
|     if(p == 0) return; | ||||
|  | ||||
|     int * pm = static_cast<int*>(p); | ||||
|     pm -= m; | ||||
|  | ||||
|     BOOST_ASSERT(*pm != adopted_scalar);    // second smart pointer to the same address | ||||
|     BOOST_ASSERT(*pm != allocated_array);   // allocated with new[] | ||||
|     BOOST_ASSERT(*pm == allocated_scalar);  // not allocated with new | ||||
|  | ||||
|     *pm = adopted_scalar; | ||||
| } | ||||
|  | ||||
| void sp_scalar_constructor_hook(void * px, std::size_t, void *) | ||||
| { | ||||
|     sp_scalar_constructor_hook(px); | ||||
| } | ||||
|  | ||||
| void sp_scalar_destructor_hook(void * p) | ||||
| { | ||||
|     if(p == 0) return; | ||||
|  | ||||
|     int * pm = static_cast<int*>(p); | ||||
|     pm -= m; | ||||
|  | ||||
|     BOOST_ASSERT(*pm == adopted_scalar);    // attempt to destroy nonmanaged block | ||||
|  | ||||
|     *pm = allocated_scalar; | ||||
| } | ||||
|  | ||||
| void sp_scalar_destructor_hook(void * px, std::size_t, void *) | ||||
| { | ||||
|     sp_scalar_destructor_hook(px); | ||||
| } | ||||
|  | ||||
| // It is not possible to handle the array hooks in a portable manner. | ||||
| // The implementation typically reserves a bit of storage for the number | ||||
| // of objects in the array, and the argument of the array hook isn't | ||||
| // equal to the return value of operator new[]. | ||||
|  | ||||
| void sp_array_constructor_hook(void * /* p */) | ||||
| { | ||||
| /* | ||||
|     if(p == 0) return; | ||||
|  | ||||
|     // adjust p depending on the implementation | ||||
|  | ||||
|     int * pm = static_cast<int*>(p); | ||||
|     pm -= m; | ||||
|  | ||||
|     BOOST_ASSERT(*pm != adopted_array);     // second smart array pointer to the same address | ||||
|     BOOST_ASSERT(*pm != allocated_scalar);  // allocated with new | ||||
|     BOOST_ASSERT(*pm == allocated_array);   // not allocated with new[] | ||||
|  | ||||
|     *pm = adopted_array; | ||||
| */ | ||||
| } | ||||
|  | ||||
| void sp_array_destructor_hook(void * /* p */) | ||||
| { | ||||
| /* | ||||
|     if(p == 0) return; | ||||
|  | ||||
|     // adjust p depending on the implementation | ||||
|  | ||||
|     int * pm = static_cast<int*>(p); | ||||
|     pm -= m; | ||||
|  | ||||
|     BOOST_ASSERT(*pm == adopted_array); // attempt to destroy nonmanaged block | ||||
|  | ||||
|     *pm = allocated_array; | ||||
| */ | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| // operator delete | ||||
|  | ||||
| void operator delete(void * p) throw() | ||||
| { | ||||
|     if(p == 0) return; | ||||
|  | ||||
|     int * pm = static_cast<int*>(p); | ||||
|     pm -= m; | ||||
|  | ||||
|     BOOST_ASSERT(*pm != deleted);           // double delete | ||||
|     BOOST_ASSERT(*pm != adopted_scalar);    // delete p.get(); | ||||
|     BOOST_ASSERT(*pm != allocated_array);   // allocated with new[] | ||||
|     BOOST_ASSERT(*pm == allocated_scalar);  // not allocated with new | ||||
|  | ||||
|     *pm = deleted; | ||||
|  | ||||
|     free(pm); | ||||
| } | ||||
|  | ||||
| #if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551) | ||||
|  | ||||
| void operator delete(void * p, nothrow_t const &) throw() | ||||
| { | ||||
|     ::operator delete(p); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| void operator delete[](void * p) throw() | ||||
| { | ||||
|     if(p == 0) return; | ||||
|  | ||||
|     int * pm = static_cast<int*>(p); | ||||
|     pm -= m; | ||||
|  | ||||
|     BOOST_ASSERT(*pm != deleted);           // double delete | ||||
|     BOOST_ASSERT(*pm != adopted_scalar);    // delete p.get(); | ||||
|     BOOST_ASSERT(*pm != allocated_scalar);  // allocated with new | ||||
|     BOOST_ASSERT(*pm == allocated_array);   // not allocated with new[] | ||||
|  | ||||
|     *pm = deleted; | ||||
|  | ||||
|     free(pm); | ||||
| } | ||||
|  | ||||
| #if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551) | ||||
|  | ||||
| void operator delete[](void * p, nothrow_t const &) throw() | ||||
| { | ||||
|     ::operator delete[](p); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
| @@ -1,12 +1,3 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| //  shared_ptr_mt_test.cpp - tests shared_ptr with multiple threads | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| @@ -18,14 +9,14 @@ | ||||
|  | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/bind.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #include <boost/smart_ptr/detail/lightweight_thread.hpp> | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #include <cstdio> | ||||
| #include <ctime> | ||||
|  | ||||
| #include <boost/detail/lightweight_thread.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
| int const n = 1024 * 1024; | ||||
| @@ -62,7 +53,7 @@ int main() | ||||
|  | ||||
|     clock_t t = clock(); | ||||
|  | ||||
|     pthread_t a[ m ]; | ||||
|     boost::detail::lw_thread_t a[ m ]; | ||||
|  | ||||
|     for( int i = 0; i < m; ++i ) | ||||
|     { | ||||
| @@ -71,7 +62,7 @@ int main() | ||||
|  | ||||
|     for( int j = 0; j < m; ++j ) | ||||
|     { | ||||
|         pthread_join( a[j], 0 ); | ||||
|         boost::detail::lw_thread_join( a[j] ); | ||||
|     } | ||||
|  | ||||
|     t = clock() - t; | ||||
|   | ||||
| @@ -1,12 +1,3 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  shared_ptr_timing_test.cpp - use to evaluate the impact of thread safety | ||||
| // | ||||
|   | ||||
| @@ -13,8 +13,8 @@ | ||||
| #include <boost/thread/shared_mutex.hpp> | ||||
| #include <boost/thread/locks.hpp> | ||||
|  | ||||
| #include <boost/detail/lightweight_mutex.hpp> | ||||
| #include <boost/detail/lightweight_thread.hpp> | ||||
| #include <boost/smart_ptr/detail/lightweight_mutex.hpp> | ||||
| #include <boost/smart_ptr/detail/lightweight_thread.hpp> | ||||
|  | ||||
| #include <vector> | ||||
| #include <numeric> | ||||
| @@ -228,7 +228,7 @@ int main( int ac, char const * av[] ) | ||||
|  | ||||
|     clock_t t = clock(); | ||||
|  | ||||
|     std::vector<pthread_t> a( m ); | ||||
|     std::vector<boost::detail::lw_thread_t> a( m ); | ||||
|  | ||||
|     for( int i = 0; i < m; ++i ) | ||||
|     { | ||||
| @@ -237,7 +237,7 @@ int main( int ac, char const * av[] ) | ||||
|  | ||||
|     for( int j = 0; j < m; ++j ) | ||||
|     { | ||||
|         pthread_join( a[ j ], 0 ); | ||||
|         boost::detail::lw_thread_join( a[ j ] ); | ||||
|     } | ||||
|  | ||||
|     t = clock() - t; | ||||
|   | ||||
| @@ -18,9 +18,9 @@ | ||||
| #include <boost/thread/locks.hpp> | ||||
| #endif | ||||
|  | ||||
| #include <boost/detail/lightweight_mutex.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/detail/lightweight_thread.hpp> | ||||
| #include <boost/smart_ptr/detail/lightweight_mutex.hpp> | ||||
| #include <boost/smart_ptr/detail/lightweight_thread.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
|  | ||||
| #include <cstdio> | ||||
| #include <ctime> | ||||
| @@ -165,7 +165,7 @@ int main() | ||||
|  | ||||
|     clock_t t = clock(); | ||||
|  | ||||
|     pthread_t a[ mr+mw ]; | ||||
|     boost::detail::lw_thread_t a[ mr+mw ]; | ||||
|  | ||||
|     for( int i = 0; i < mr; ++i ) | ||||
|     { | ||||
| @@ -179,7 +179,7 @@ int main() | ||||
|  | ||||
|     for( int j = 0; j < mr+mw; ++j ) | ||||
|     { | ||||
|         pthread_join( a[ j ], 0 ); | ||||
|         boost::detail::lw_thread_join( a[ j ] ); | ||||
|     } | ||||
|  | ||||
|     t = clock() - t; | ||||
|   | ||||
| @@ -1,12 +1,3 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| //  weak_ptr_mt_test.cpp | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| @@ -19,15 +10,15 @@ | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/weak_ptr.hpp> | ||||
| #include <boost/bind.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #include <boost/smart_ptr/detail/lightweight_thread.hpp> | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #include <cstdio> | ||||
| #include <ctime> | ||||
| #include <cstdlib> | ||||
|  | ||||
| #include <boost/detail/lightweight_thread.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
| int const n = 16384; | ||||
| @@ -100,7 +91,7 @@ int main() | ||||
|  | ||||
|     clock_t t = clock(); | ||||
|  | ||||
|     pthread_t a[ m ]; | ||||
|     boost::detail::lw_thread_t a[ m ]; | ||||
|  | ||||
|     for( int i = 0; i < m; ++i ) | ||||
|     { | ||||
| @@ -111,7 +102,7 @@ int main() | ||||
|  | ||||
|     for( int j = 0; j < m; ++j ) | ||||
|     { | ||||
|         pthread_join( a[j], 0 ); | ||||
|         boost::detail::lw_thread_join( a[j] ); | ||||
|     } | ||||
|  | ||||
|     t = clock() - t; | ||||
|   | ||||
| @@ -1,12 +1,3 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  weak_ptr_timing_test.cpp | ||||
| // | ||||
| @@ -20,6 +11,7 @@ | ||||
|  | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/weak_ptr.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #include <vector> | ||||
| #include <cstdio> | ||||
|   | ||||
| @@ -1,20 +1,13 @@ | ||||
| #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
| // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
| #include <boost/config/header_deprecated.hpp> | ||||
|  | ||||
| // | ||||
| //  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 | ||||
| BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/atomic_count.hpp>") | ||||
|  | ||||
| #include <boost/smart_ptr/detail/atomic_count.hpp> | ||||
|  | ||||
|   | ||||
| @@ -1,21 +1,13 @@ | ||||
| #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
| // Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
| #include <boost/config/header_deprecated.hpp> | ||||
|  | ||||
| // | ||||
| //  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 | ||||
| // | ||||
| BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/lightweight_mutex.hpp>") | ||||
|  | ||||
| #include <boost/smart_ptr/detail/lightweight_mutex.hpp> | ||||
|  | ||||
|   | ||||
| @@ -1,135 +1,15 @@ | ||||
| #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
| // Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| // Copyright (c) 2008, 2018 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
| #include <boost/config/header_deprecated.hpp> | ||||
|  | ||||
| //  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 | ||||
| BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/lightweight_thread.hpp>") | ||||
|  | ||||
| #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 | ||||
| #include <boost/smart_ptr/detail/lightweight_thread.hpp> | ||||
|  | ||||
| #endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED | ||||
|   | ||||
| @@ -1,22 +1,14 @@ | ||||
| #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
| // Copyright (c) 2003 David Abrahams | ||||
| // Copyright (c) 2003 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
| #include <boost/config/header_deprecated.hpp> | ||||
|  | ||||
| // | ||||
| //  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 | ||||
| // | ||||
| BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/quick_allocator.hpp>") | ||||
|  | ||||
| #include <boost/smart_ptr/detail/quick_allocator.hpp> | ||||
|  | ||||
|   | ||||
| @@ -10,49 +10,39 @@ | ||||
| #ifndef BOOST_POINTER_CAST_HPP | ||||
| #define BOOST_POINTER_CAST_HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_noexcept.hpp> | ||||
| #include <memory> | ||||
| #include <type_traits> | ||||
|  | ||||
| namespace boost {  | ||||
|  | ||||
| //static_pointer_cast overload for raw pointers | ||||
| template<class T, class U> | ||||
| inline T* static_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT | ||||
| inline T* static_pointer_cast(U *ptr) noexcept | ||||
| {   | ||||
|    return static_cast<T*>(ptr); | ||||
| } | ||||
|  | ||||
| //dynamic_pointer_cast overload for raw pointers | ||||
| template<class T, class U> | ||||
| inline T* dynamic_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT | ||||
| inline T* dynamic_pointer_cast(U *ptr) noexcept | ||||
| {   | ||||
|    return dynamic_cast<T*>(ptr); | ||||
| } | ||||
|  | ||||
| //const_pointer_cast overload for raw pointers | ||||
| template<class T, class U> | ||||
| inline T* const_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT | ||||
| inline T* const_pointer_cast(U *ptr) noexcept | ||||
| {   | ||||
|    return const_cast<T*>(ptr); | ||||
| } | ||||
|  | ||||
| //reinterpret_pointer_cast overload for raw pointers | ||||
| template<class T, class U> | ||||
| inline T* reinterpret_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT | ||||
| inline T* reinterpret_pointer_cast(U *ptr) noexcept | ||||
| {   | ||||
|    return reinterpret_cast<T*>(ptr); | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_SMART_PTR ) | ||||
|  | ||||
| #include <boost/type_traits/has_virtual_destructor.hpp> | ||||
| #include <boost/static_assert.hpp> | ||||
| #include <memory> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| //static_pointer_cast overload for std::shared_ptr | ||||
| using std::static_pointer_cast; | ||||
|  | ||||
| @@ -63,7 +53,7 @@ using std::dynamic_pointer_cast; | ||||
| using std::const_pointer_cast; | ||||
|  | ||||
| //reinterpret_pointer_cast overload for std::shared_ptr | ||||
| template<class T, class U> std::shared_ptr<T> reinterpret_pointer_cast(const std::shared_ptr<U> & r ) BOOST_SP_NOEXCEPT | ||||
| template<class T, class U> std::shared_ptr<T> reinterpret_pointer_cast(const std::shared_ptr<U> & r ) noexcept | ||||
| { | ||||
|     (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); | ||||
|  | ||||
| @@ -74,7 +64,7 @@ template<class T, class U> std::shared_ptr<T> reinterpret_pointer_cast(const std | ||||
| } | ||||
|  | ||||
| //static_pointer_cast overload for std::unique_ptr | ||||
| template<class T, class U> std::unique_ptr<T> static_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT | ||||
| template<class T, class U> std::unique_ptr<T> static_pointer_cast( std::unique_ptr<U> && r ) noexcept | ||||
| { | ||||
|     (void) static_cast< T* >( static_cast< U* >( 0 ) ); | ||||
|  | ||||
| @@ -84,11 +74,11 @@ template<class T, class U> std::unique_ptr<T> static_pointer_cast( std::unique_p | ||||
| } | ||||
|  | ||||
| //dynamic_pointer_cast overload for std::unique_ptr | ||||
| template<class T, class U> std::unique_ptr<T> dynamic_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT | ||||
| template<class T, class U> std::unique_ptr<T> dynamic_pointer_cast( std::unique_ptr<U> && r ) noexcept | ||||
| { | ||||
|     (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); | ||||
|  | ||||
|     BOOST_STATIC_ASSERT_MSG( boost::has_virtual_destructor<T>::value, "The target of dynamic_pointer_cast must have a virtual destructor." ); | ||||
|     static_assert( std::has_virtual_destructor<T>::value, "The target of dynamic_pointer_cast must have a virtual destructor." ); | ||||
|  | ||||
|     T * p = dynamic_cast<T*>( r.get() ); | ||||
|     if( p ) r.release(); | ||||
| @@ -96,7 +86,7 @@ template<class T, class U> std::unique_ptr<T> dynamic_pointer_cast( std::unique_ | ||||
| } | ||||
|  | ||||
| //const_pointer_cast overload for std::unique_ptr | ||||
| template<class T, class U> std::unique_ptr<T> const_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT | ||||
| template<class T, class U> std::unique_ptr<T> const_pointer_cast( std::unique_ptr<U> && r ) noexcept | ||||
| { | ||||
|     (void) const_cast< T* >( static_cast< U* >( 0 ) ); | ||||
|  | ||||
| @@ -106,7 +96,7 @@ template<class T, class U> std::unique_ptr<T> const_pointer_cast( std::unique_pt | ||||
| } | ||||
|  | ||||
| //reinterpret_pointer_cast overload for std::unique_ptr | ||||
| template<class T, class U> std::unique_ptr<T> reinterpret_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT | ||||
| template<class T, class U> std::unique_ptr<T> reinterpret_pointer_cast( std::unique_ptr<U> && r ) noexcept | ||||
| { | ||||
|     (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); | ||||
|  | ||||
| @@ -117,6 +107,4 @@ template<class T, class U> std::unique_ptr<T> reinterpret_pointer_cast( std::uni | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #if !defined( BOOST_NO_CXX11_SMART_PTR ) | ||||
|  | ||||
| #endif   //BOOST_POINTER_CAST_HPP | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
| Copyright 2017 Glen Joseph Fernandes | ||||
| Copyright 2017-2019 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| @@ -10,38 +10,25 @@ Distributed under the Boost Software License, Version 1.0. | ||||
|  | ||||
| #include <boost/smart_ptr/allocate_shared_array.hpp> | ||||
| #include <boost/smart_ptr/local_shared_ptr.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_type_traits.hpp> | ||||
| #include <type_traits> | ||||
|  | ||||
| namespace boost { | ||||
| namespace detail { | ||||
|  | ||||
| template<class> | ||||
| struct lsp_if_array { }; | ||||
|  | ||||
| template<class T> | ||||
| struct lsp_if_array<T[]> { | ||||
|     typedef boost::local_shared_ptr<T[]> type; | ||||
| }; | ||||
|  | ||||
| template<class> | ||||
| struct lsp_if_size_array { }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct lsp_if_size_array<T[N]> { | ||||
|     typedef boost::local_shared_ptr<T[N]> type; | ||||
| }; | ||||
|  | ||||
| class lsp_array_base | ||||
| class BOOST_SYMBOL_VISIBLE lsp_array_base | ||||
|     : public local_counted_base { | ||||
| public: | ||||
|     void set(sp_counted_base* base) BOOST_SP_NOEXCEPT { | ||||
|     void set(sp_counted_base* base) noexcept { | ||||
|         count_ = shared_count(base); | ||||
|     } | ||||
|  | ||||
|     virtual void local_cb_destroy() BOOST_SP_NOEXCEPT { | ||||
|     void local_cb_destroy() noexcept override { | ||||
|         shared_count().swap(count_); | ||||
|     } | ||||
|  | ||||
|     virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT { | ||||
|     shared_count local_cb_get_shared_count() const | ||||
|         noexcept override { | ||||
|         return count_; | ||||
|     } | ||||
|  | ||||
| @@ -54,10 +41,10 @@ class lsp_array_state | ||||
|     : public sp_array_state<A> { | ||||
| public: | ||||
|     template<class U> | ||||
|     lsp_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT | ||||
|     lsp_array_state(const U& other, std::size_t size) noexcept | ||||
|         : sp_array_state<A>(other, size) { } | ||||
|  | ||||
|     lsp_array_base& base() BOOST_SP_NOEXCEPT { | ||||
|     lsp_array_base& base() noexcept { | ||||
|         return base_; | ||||
|     } | ||||
|  | ||||
| @@ -70,10 +57,10 @@ class lsp_size_array_state | ||||
|     : public sp_size_array_state<A, N> { | ||||
| public: | ||||
|     template<class U> | ||||
|     lsp_size_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT | ||||
|     lsp_size_array_state(const U& other, std::size_t size) noexcept | ||||
|         : sp_size_array_state<A, N>(other, size) { } | ||||
|  | ||||
|     lsp_array_base& base() BOOST_SP_NOEXCEPT { | ||||
|     lsp_array_base& base() noexcept { | ||||
|         return base_; | ||||
|     } | ||||
|  | ||||
| @@ -84,143 +71,108 @@ private: | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared(const A& allocator, std::size_t count) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::lsp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, start); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start, | ||||
|         &local); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|         count = std::extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, size> state; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, count> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, start); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start, | ||||
|         &local); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared(const A& allocator, std::size_t count, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::lsp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, | ||||
|         reinterpret_cast<const scalar*>(&value), | ||||
|         detail::sp_array_count<type>::value, start); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count, value); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start, | ||||
|         &local); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared(const A& allocator, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|         count = std::extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, size> state; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, count> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, | ||||
|         reinterpret_cast<const scalar*>(&value), | ||||
|         detail::sp_array_count<type>::value, start); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count, value); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start, | ||||
|         &local); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared_noinit(const A& allocator, std::size_t count) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::lsp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state, false> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | ||||
|         size, start); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator), | ||||
|         count); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared_noinit(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, size> state; | ||||
|     typedef detail::sp_array_base<state, false> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | ||||
|         size, start); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator)); | ||||
| } | ||||
|  | ||||
| } /* boost */ | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
| Copyright 2012-2017 Glen Joseph Fernandes | ||||
| Copyright 2012-2019 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| @@ -8,88 +8,20 @@ Distributed under the Boost Software License, Version 1.0. | ||||
| #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP | ||||
| #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP | ||||
|  | ||||
| #include <boost/core/allocator_access.hpp> | ||||
| #include <boost/core/alloc_construct.hpp> | ||||
| #include <boost/core/first_scalar.hpp> | ||||
| #include <boost/smart_ptr/shared_ptr.hpp> | ||||
| #include <boost/type_traits/alignment_of.hpp> | ||||
| #include <boost/type_traits/has_trivial_assign.hpp> | ||||
| #include <boost/type_traits/has_trivial_constructor.hpp> | ||||
| #include <boost/type_traits/has_trivial_destructor.hpp> | ||||
| #include <boost/type_traits/type_with_alignment.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_type_traits.hpp> | ||||
| #include <type_traits> | ||||
|  | ||||
| namespace boost { | ||||
| namespace detail { | ||||
|  | ||||
| template<class> | ||||
| struct sp_if_array { }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_if_array<T[]> { | ||||
|     typedef boost::shared_ptr<T[]> type; | ||||
| }; | ||||
|  | ||||
| template<class> | ||||
| 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; | ||||
| }; | ||||
|  | ||||
| template<class> | ||||
| struct sp_array_element { }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_element<T[]> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_element<T[N]> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_scalar<T[N]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_scalar<const T[N]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_scalar<volatile T[N]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_scalar<const volatile T[N]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar<T[]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar<const T[]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar<volatile T[]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar<const volatile T[]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| struct sp_array_element { | ||||
|     typedef typename std::remove_cv<typename | ||||
|         std::remove_extent<T>::type>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| @@ -120,242 +52,28 @@ struct sp_align_up { | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_ALLOCATOR) | ||||
| template<class A, class T> | ||||
| struct sp_bind_allocator { | ||||
|     typedef typename std::allocator_traits<A>::template rebind_alloc<T> type; | ||||
| }; | ||||
| #else | ||||
| template<class A, class T> | ||||
| struct sp_bind_allocator { | ||||
|     typedef typename A::template rebind<T>::other type; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| template<class T> | ||||
| BOOST_CONSTEXPR inline std::size_t | ||||
| sp_objects(std::size_t size) BOOST_SP_NOEXCEPT | ||||
| constexpr inline std::size_t | ||||
| sp_objects(std::size_t size) noexcept | ||||
| { | ||||
|     return (size + sizeof(T) - 1) / sizeof(T); | ||||
| } | ||||
|  | ||||
| template<bool, class = void> | ||||
| struct sp_enable { }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_enable<true, T> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && boost::has_trivial_destructor<T>::value>::type | ||||
| sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { } | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && | ||||
|     !boost::has_trivial_destructor<T>::value>::type | ||||
| sp_array_destroy(A&, T* start, std::size_t size) | ||||
| { | ||||
|     while (size > 0) { | ||||
|         start[--size].~T(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_ALLOCATOR) | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<E>::type | ||||
| sp_array_destroy(A& allocator, T* start, std::size_t size) | ||||
| { | ||||
|     while (size > 0) { | ||||
|         std::allocator_traits<A>::destroy(allocator, start + --size); | ||||
|     } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && | ||||
|     boost::has_trivial_constructor<T>::value && | ||||
|     boost::has_trivial_assign<T>::value>::type | ||||
| sp_array_construct(A&, T* start, std::size_t size) | ||||
| { | ||||
|     for (std::size_t i = 0; i < size; ++i) { | ||||
|         start[i] = T(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && | ||||
|     boost::has_trivial_constructor<T>::value && | ||||
|     boost::has_trivial_assign<T>::value>::type | ||||
| sp_array_construct(A&, T* start, std::size_t size, const T* list, | ||||
|     std::size_t count) | ||||
| { | ||||
|     for (std::size_t i = 0; i < size; ++i) { | ||||
|         start[i] = list[i % count]; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #if !defined(BOOST_NO_EXCEPTIONS) | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && | ||||
|     !(boost::has_trivial_constructor<T>::value && | ||||
|       boost::has_trivial_assign<T>::value)>::type | ||||
| sp_array_construct(A& none, T* start, std::size_t size) | ||||
| { | ||||
|     std::size_t i = 0; | ||||
|     try { | ||||
|         for (; i < size; ++i) { | ||||
|             ::new(static_cast<void*>(start + i)) T(); | ||||
|         } | ||||
|     } catch (...) { | ||||
|         sp_array_destroy<E>(none, start, i); | ||||
|         throw; | ||||
|     } | ||||
| } | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && | ||||
|     !(boost::has_trivial_constructor<T>::value && | ||||
|       boost::has_trivial_assign<T>::value)>::type | ||||
| sp_array_construct(A& none, T* start, std::size_t size, const T* list, | ||||
|     std::size_t count) | ||||
| { | ||||
|     std::size_t i = 0; | ||||
|     try { | ||||
|         for (; i < size; ++i) { | ||||
|             ::new(static_cast<void*>(start + i)) T(list[i % count]); | ||||
|         } | ||||
|     } catch (...) { | ||||
|         sp_array_destroy<E>(none, start, i); | ||||
|         throw; | ||||
|     } | ||||
| } | ||||
| #else | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && | ||||
|     !(boost::has_trivial_constructor<T>::value && | ||||
|       boost::has_trivial_assign<T>::value)>::type | ||||
| sp_array_construct(A&, T* start, std::size_t size) | ||||
| { | ||||
|     for (std::size_t i = 0; i < size; ++i) { | ||||
|         ::new(static_cast<void*>(start + i)) T(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && | ||||
|     !(boost::has_trivial_constructor<T>::value && | ||||
|       boost::has_trivial_assign<T>::value)>::type | ||||
| sp_array_construct(A&, T* start, std::size_t size, const T* list, | ||||
|     std::size_t count) | ||||
| { | ||||
|     for (std::size_t i = 0; i < size; ++i) { | ||||
|         ::new(static_cast<void*>(start + i)) T(list[i % count]); | ||||
|     } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_ALLOCATOR) | ||||
| #if !defined(BOOST_NO_EXCEPTIONS) | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<E>::type | ||||
| sp_array_construct(A& allocator, T* start, std::size_t size) | ||||
| { | ||||
|     std::size_t i = 0; | ||||
|     try { | ||||
|         for (i = 0; i < size; ++i) { | ||||
|             std::allocator_traits<A>::construct(allocator, start + i); | ||||
|         } | ||||
|     } catch (...) { | ||||
|         sp_array_destroy<E>(allocator, start, i); | ||||
|         throw; | ||||
|     } | ||||
| } | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<E>::type | ||||
| sp_array_construct(A& allocator, T* start, std::size_t size, const T* list, | ||||
|     std::size_t count) | ||||
| { | ||||
|     std::size_t i = 0; | ||||
|     try { | ||||
|         for (i = 0; i < size; ++i) { | ||||
|             std::allocator_traits<A>::construct(allocator, start + i, | ||||
|                 list[i % count]); | ||||
|         } | ||||
|     } catch (...) { | ||||
|         sp_array_destroy<E>(allocator, start, i); | ||||
|         throw; | ||||
|     } | ||||
| } | ||||
| #else | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<E>::type | ||||
| sp_array_construct(A& allocator, T* start, std::size_t size) | ||||
| { | ||||
|     for (std::size_t i = 0; i < size; ++i) { | ||||
|         std::allocator_traits<A>::construct(allocator, start + i); | ||||
|     } | ||||
| } | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<E>::type | ||||
| sp_array_construct(A& allocator, T* start, std::size_t size, const T* list, | ||||
|     std::size_t count) | ||||
| { | ||||
|     for (std::size_t i = 0; i < size; ++i) { | ||||
|         std::allocator_traits<A>::construct(allocator, start + i, | ||||
|             list[i % count]); | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| template<class A, class T> | ||||
| inline typename sp_enable<boost::has_trivial_constructor<T>::value>::type | ||||
| sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { } | ||||
|  | ||||
| #if !defined(BOOST_NO_EXCEPTIONS) | ||||
| template<class A, class T> | ||||
| inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type | ||||
| sp_array_default(A& none, T* start, std::size_t size) | ||||
| { | ||||
|     std::size_t i = 0; | ||||
|     try { | ||||
|         for (; i < size; ++i) { | ||||
|             ::new(static_cast<void*>(start + i)) T; | ||||
|         } | ||||
|     } catch (...) { | ||||
|         sp_array_destroy<false>(none, start, i); | ||||
|         throw; | ||||
|     } | ||||
| } | ||||
| #else | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type | ||||
| sp_array_default(A&, T* start, std::size_t size) | ||||
| { | ||||
|     for (std::size_t i = 0; i < size; ++i) { | ||||
|         ::new(static_cast<void*>(start + i)) T; | ||||
|     } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| template<class A> | ||||
| class sp_array_state { | ||||
| public: | ||||
|     typedef A type; | ||||
|  | ||||
|     template<class U> | ||||
|     sp_array_state(const U& allocator, std::size_t size) BOOST_SP_NOEXCEPT | ||||
|         : allocator_(allocator), | ||||
|           size_(size) { } | ||||
|     sp_array_state(const U& _allocator, std::size_t _size) noexcept | ||||
|         : allocator_(_allocator), | ||||
|           size_(_size) { } | ||||
|  | ||||
|     A& allocator() BOOST_SP_NOEXCEPT { | ||||
|     A& allocator() noexcept { | ||||
|         return allocator_; | ||||
|     } | ||||
|  | ||||
|     std::size_t size() const BOOST_SP_NOEXCEPT { | ||||
|     std::size_t size() const noexcept { | ||||
|         return size_; | ||||
|     } | ||||
|  | ||||
| @@ -370,14 +88,14 @@ public: | ||||
|     typedef A type; | ||||
|  | ||||
|     template<class U> | ||||
|     sp_size_array_state(const U& allocator, std::size_t) BOOST_SP_NOEXCEPT | ||||
|         : allocator_(allocator) { } | ||||
|     sp_size_array_state(const U& _allocator, std::size_t) noexcept | ||||
|         : allocator_(_allocator) { } | ||||
|  | ||||
|     A& allocator() BOOST_SP_NOEXCEPT { | ||||
|     A& allocator() noexcept { | ||||
|         return allocator_; | ||||
|     } | ||||
|  | ||||
|     BOOST_CONSTEXPR std::size_t size() const BOOST_SP_NOEXCEPT { | ||||
|     constexpr std::size_t size() const noexcept { | ||||
|         return N; | ||||
|     } | ||||
|  | ||||
| @@ -385,34 +103,11 @@ private: | ||||
|     A allocator_; | ||||
| }; | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_ALLOCATOR) | ||||
| template<class A> | ||||
| struct sp_use_construct { | ||||
|     enum { | ||||
|         value = true | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_use_construct<std::allocator<T> > { | ||||
|     enum { | ||||
|         value = false | ||||
|     }; | ||||
| }; | ||||
| #else | ||||
| template<class> | ||||
| struct sp_use_construct { | ||||
|     enum { | ||||
|         value = false | ||||
|     }; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| template<class T, class U> | ||||
| struct sp_array_alignment { | ||||
|     enum { | ||||
|         value = sp_max_size<boost::alignment_of<T>::value, | ||||
|             boost::alignment_of<U>::value>::value | ||||
|         value = sp_max_size<std::alignment_of<T>::value, | ||||
|             std::alignment_of<U>::value>::value | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| @@ -423,39 +118,32 @@ struct sp_array_offset { | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| template<class T, class U> | ||||
| struct sp_array_storage { | ||||
|     enum { | ||||
|         value = sp_array_alignment<T, U>::value | ||||
|     }; | ||||
|     typedef typename boost::type_with_alignment<value>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T, class U> | ||||
| template<class U, class T> | ||||
| inline U* | ||||
| sp_array_start(void* base) BOOST_SP_NOEXCEPT | ||||
| sp_array_start(T* base) noexcept | ||||
| { | ||||
|     enum { | ||||
|         size = sp_array_offset<T, U>::value | ||||
|     }; | ||||
|     return reinterpret_cast<U*>(static_cast<char*>(base) + size); | ||||
|     return reinterpret_cast<U*>(reinterpret_cast<char*>(base) + size); | ||||
| } | ||||
|  | ||||
| template<class A, class T> | ||||
| class sp_array_creator { | ||||
|     typedef typename A::value_type scalar; | ||||
|     typedef typename A::value_type element; | ||||
|  | ||||
|     enum { | ||||
|         offset = sp_array_offset<T, scalar>::value | ||||
|         offset = sp_array_offset<T, element>::value | ||||
|     }; | ||||
|  | ||||
|     typedef typename sp_array_storage<T, scalar>::type type; | ||||
|     typedef typename sp_type_with_alignment<sp_array_alignment<T, | ||||
|         element>::value>::type type; | ||||
|  | ||||
| public: | ||||
|     template<class U> | ||||
|     sp_array_creator(const U& other, std::size_t size) BOOST_SP_NOEXCEPT | ||||
|     sp_array_creator(const U& other, std::size_t size) noexcept | ||||
|         : other_(other), | ||||
|           size_(sp_objects<type>(offset + sizeof(scalar) * size)) { } | ||||
|           size_(sp_objects<type>(offset + sizeof(element) * size)) { } | ||||
|  | ||||
|     T* create() { | ||||
|         return reinterpret_cast<T*>(other_.allocate(size_)); | ||||
| @@ -466,14 +154,12 @@ public: | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     typename sp_bind_allocator<A, type>::type other_; | ||||
|     typename boost::allocator_rebind<A, type>::type other_; | ||||
|     std::size_t size_; | ||||
| }; | ||||
|  | ||||
| struct sp_default { }; | ||||
|  | ||||
| template<class T, bool E = sp_use_construct<T>::value> | ||||
| class sp_array_base | ||||
| template<class T> | ||||
| class BOOST_SYMBOL_VISIBLE sp_array_base | ||||
|     : public sp_counted_base { | ||||
|     typedef typename T::type allocator; | ||||
|  | ||||
| @@ -481,50 +167,51 @@ public: | ||||
|     typedef typename allocator::value_type type; | ||||
|  | ||||
|     template<class A> | ||||
|     sp_array_base(const A& other, std::size_t size, type* start) | ||||
|     sp_array_base(const A& other, type* start, std::size_t size) | ||||
|         : state_(other, size) { | ||||
|         sp_array_construct<E>(state_.allocator(), start, state_.size()); | ||||
|         boost::alloc_construct_n(state_.allocator(), | ||||
|             boost::first_scalar(start), | ||||
|             state_.size() * sp_array_count<type>::value); | ||||
|     } | ||||
|  | ||||
|     template<class A> | ||||
|     sp_array_base(const A& other, std::size_t size, const type* list, | ||||
|         std::size_t count, type* start) | ||||
|     template<class A, class U> | ||||
|     sp_array_base(const A& other, type* start, std::size_t size, const U& list) | ||||
|         : state_(other, size) { | ||||
|         sp_array_construct<E>(state_.allocator(), start, state_.size(), list, | ||||
|             count); | ||||
|         enum { | ||||
|             count = sp_array_count<type>::value | ||||
|         }; | ||||
|         boost::alloc_construct_n(state_.allocator(), | ||||
|             boost::first_scalar(start), state_.size() * count, | ||||
|             boost::first_scalar(&list), count); | ||||
|     } | ||||
|  | ||||
|     template<class A> | ||||
|     sp_array_base(sp_default, const A& other, std::size_t size, type* start) | ||||
|         : state_(other, size) { | ||||
|         sp_array_default(state_.allocator(), start, state_.size()); | ||||
|     } | ||||
|  | ||||
|     T& state() BOOST_SP_NOEXCEPT { | ||||
|     T& state() noexcept { | ||||
|         return state_; | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() { | ||||
|         sp_array_destroy<E>(state_.allocator(), | ||||
|             sp_array_start<sp_array_base, type>(this), state_.size()); | ||||
|     void dispose() noexcept override { | ||||
|         boost::alloc_destroy_n(state_.allocator(), | ||||
|             boost::first_scalar(sp_array_start<type>(this)), | ||||
|             state_.size() * sp_array_count<type>::value); | ||||
|     } | ||||
|  | ||||
|     virtual void destroy() { | ||||
|     void destroy() noexcept override { | ||||
|         sp_array_creator<allocator, sp_array_base> other(state_.allocator(), | ||||
|             state_.size()); | ||||
|         this->~sp_array_base(); | ||||
|         other.destroy(this); | ||||
|     } | ||||
|  | ||||
|     virtual void* get_deleter(const sp_typeinfo&) { | ||||
|     void* get_deleter(const sp_typeinfo_&) noexcept override { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void* get_local_deleter(const sp_typeinfo&) { | ||||
|     void* get_local_deleter(const sp_typeinfo_&) | ||||
|         noexcept override { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void* get_untyped_deleter() { | ||||
|     void* get_untyped_deleter() noexcept override { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
| @@ -546,11 +233,11 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     T* get() const { | ||||
|     T* get() const noexcept { | ||||
|         return result_; | ||||
|     } | ||||
|  | ||||
|     void release() { | ||||
|     void release() noexcept { | ||||
|         result_ = 0; | ||||
|     } | ||||
|  | ||||
| @@ -565,131 +252,93 @@ private: | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator, std::size_t count) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::sp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, start); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), start, | ||||
|         detail::shared_count(static_cast<detail::sp_counted_base*>(node))); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_size_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|         count = std::extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::sp_size_array_state<other, size> state; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::sp_size_array_state<other, std::extent<T>::value> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, start); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), start, | ||||
|         detail::shared_count(static_cast<detail::sp_counted_base*>(node))); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator, std::size_t count, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::sp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, | ||||
|         reinterpret_cast<const scalar*>(&value), | ||||
|         detail::sp_array_count<type>::value, start); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count, value); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), start, | ||||
|         detail::shared_count(static_cast<detail::sp_counted_base*>(node))); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_size_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|         count = std::extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::sp_size_array_state<other, size> state; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::sp_size_array_state<other, std::extent<T>::value> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, | ||||
|         reinterpret_cast<const scalar*>(&value), | ||||
|         detail::sp_array_count<type>::value, start); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count, value); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), start, | ||||
|         detail::shared_count(static_cast<detail::sp_counted_base*>(node))); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared_noinit(const A& allocator, std::size_t count) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::sp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state, false> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | ||||
|         size, start); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return boost::allocate_shared<T>(boost::noinit_adapt(allocator), count); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_size_array<T>::type | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared_noinit(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::sp_size_array_state<other, size> state; | ||||
|     typedef detail::sp_array_base<state, false> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | ||||
|         size, start); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return boost::allocate_shared<T>(boost::noinit_adapt(allocator)); | ||||
| } | ||||
|  | ||||
| } /* boost */ | ||||
|   | ||||
							
								
								
									
										466
									
								
								include/boost/smart_ptr/allocate_unique.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										466
									
								
								include/boost/smart_ptr/allocate_unique.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,466 @@ | ||||
| /* | ||||
| Copyright 2019-2021 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| (http://www.boost.org/LICENSE_1_0.txt) | ||||
| */ | ||||
| #ifndef BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP | ||||
| #define BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP | ||||
|  | ||||
| #include <boost/core/allocator_access.hpp> | ||||
| #include <boost/core/alloc_construct.hpp> | ||||
| #include <boost/core/empty_value.hpp> | ||||
| #include <boost/core/first_scalar.hpp> | ||||
| #include <boost/core/noinit_adaptor.hpp> | ||||
| #include <boost/core/pointer_traits.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_type_traits.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <memory> | ||||
| #include <utility> | ||||
| #include <cstddef> | ||||
| #include <type_traits> | ||||
|  | ||||
| namespace boost { | ||||
| namespace detail { | ||||
|  | ||||
| template<class T> | ||||
| struct sp_alloc_size { | ||||
|     static constexpr std::size_t value = 1; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_alloc_size<T[]> { | ||||
|     static constexpr std::size_t value = sp_alloc_size<T>::value; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_alloc_size<T[N]> { | ||||
|     static constexpr std::size_t value = N * sp_alloc_size<T>::value; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_alloc_result { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_alloc_result<T[N]> { | ||||
|     typedef T type[]; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_alloc_value { | ||||
|     typedef typename std::remove_cv<typename | ||||
|         std::remove_extent<T>::type>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T, class P> | ||||
| class sp_alloc_ptr { | ||||
| public: | ||||
|     typedef T element_type; | ||||
|  | ||||
|     sp_alloc_ptr() noexcept | ||||
|         : p_() { } | ||||
|  | ||||
| #if defined(BOOST_MSVC) && BOOST_MSVC == 1600 | ||||
|     sp_alloc_ptr(T* p) noexcept | ||||
|         : p_(const_cast<typename std::remove_cv<T>::type*>(p)) { } | ||||
| #endif | ||||
|  | ||||
|     sp_alloc_ptr(std::size_t, P p) noexcept | ||||
|         : p_(p) { } | ||||
|  | ||||
|     sp_alloc_ptr(std::nullptr_t) noexcept | ||||
|         : p_() { } | ||||
|  | ||||
|     T& operator*() const { | ||||
|         return *p_; | ||||
|     } | ||||
|  | ||||
|     T* operator->() const noexcept { | ||||
|         return boost::to_address(p_); | ||||
|     } | ||||
|  | ||||
|     explicit operator bool() const noexcept { | ||||
|         return !!p_; | ||||
|     } | ||||
|  | ||||
|     bool operator!() const noexcept { | ||||
|         return !p_; | ||||
|     } | ||||
|  | ||||
|     P ptr() const noexcept { | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     static constexpr std::size_t size() noexcept { | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
| #if defined(BOOST_MSVC) && BOOST_MSVC < 1910 | ||||
|     static sp_alloc_ptr pointer_to(T& v) { | ||||
|         return sp_alloc_ptr(1, | ||||
|             std::pointer_traits<P>::pointer_to(const_cast<typename | ||||
|                 std::remove_cv<T>::type&>(v))); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| private: | ||||
|     P p_; | ||||
| }; | ||||
|  | ||||
| template<class T, class P> | ||||
| class sp_alloc_ptr<T[], P> { | ||||
| public: | ||||
|     typedef T element_type; | ||||
|  | ||||
|     sp_alloc_ptr() noexcept | ||||
|         : p_() { } | ||||
|  | ||||
|     sp_alloc_ptr(std::size_t n, P p) noexcept | ||||
|         : p_(p) | ||||
|         , n_(n) { } | ||||
|  | ||||
|     sp_alloc_ptr(std::nullptr_t) noexcept | ||||
|         : p_() { } | ||||
|  | ||||
|     T& operator[](std::size_t i) const { | ||||
|         return p_[i]; | ||||
|     } | ||||
|  | ||||
|     explicit operator bool() const noexcept { | ||||
|         return !!p_; | ||||
|     } | ||||
|  | ||||
|     bool operator!() const noexcept { | ||||
|         return !p_; | ||||
|     } | ||||
|  | ||||
|     P ptr() const noexcept { | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     std::size_t size() const noexcept { | ||||
|         return n_; | ||||
|     } | ||||
|  | ||||
| #if defined(BOOST_MSVC) && BOOST_MSVC < 1910 | ||||
|     static sp_alloc_ptr pointer_to(T& v) { | ||||
|         return sp_alloc_ptr(n_, | ||||
|             std::pointer_traits<P>::pointer_to(const_cast<typename | ||||
|                 std::remove_cv<T>::type&>(v))); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| private: | ||||
|     P p_; | ||||
|     std::size_t n_; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N, class P> | ||||
| class sp_alloc_ptr<T[N], P> { | ||||
| public: | ||||
|     typedef T element_type; | ||||
|  | ||||
|     sp_alloc_ptr() noexcept | ||||
|         : p_() { } | ||||
|  | ||||
|     sp_alloc_ptr(std::size_t, P p) noexcept | ||||
|         : p_(p) { } | ||||
|  | ||||
|     sp_alloc_ptr(std::nullptr_t) noexcept | ||||
|         : p_() { } | ||||
|  | ||||
|     T& operator[](std::size_t i) const { | ||||
|         return p_[i]; | ||||
|     } | ||||
|  | ||||
|     explicit operator bool() const noexcept { | ||||
|         return !!p_; | ||||
|     } | ||||
|  | ||||
|     bool operator!() const noexcept { | ||||
|         return !p_; | ||||
|     } | ||||
|  | ||||
|     P ptr() const noexcept { | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     static constexpr std::size_t size() noexcept { | ||||
|         return N; | ||||
|     } | ||||
|  | ||||
| #if defined(BOOST_MSVC) && BOOST_MSVC < 1910 | ||||
|     static sp_alloc_ptr pointer_to(T& v) { | ||||
|         return sp_alloc_ptr(N, | ||||
|             std::pointer_traits<P>::pointer_to(const_cast<typename | ||||
|                 std::remove_cv<T>::type&>(v))); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| private: | ||||
|     P p_; | ||||
| }; | ||||
|  | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator==(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs) | ||||
| { | ||||
|     return lhs.ptr() == rhs.ptr(); | ||||
| } | ||||
|  | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator!=(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs) | ||||
| { | ||||
|     return !(lhs == rhs); | ||||
| } | ||||
|  | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator==(const sp_alloc_ptr<T, P>& lhs, | ||||
|     std::nullptr_t) noexcept | ||||
| { | ||||
|     return !lhs.ptr(); | ||||
| } | ||||
|  | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator==(std::nullptr_t, | ||||
|     const sp_alloc_ptr<T, P>& rhs) noexcept | ||||
| { | ||||
|     return !rhs.ptr(); | ||||
| } | ||||
|  | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator!=(const sp_alloc_ptr<T, P>& lhs, | ||||
|     std::nullptr_t) noexcept | ||||
| { | ||||
|     return !!lhs.ptr(); | ||||
| } | ||||
|  | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator!=(std::nullptr_t, | ||||
|     const sp_alloc_ptr<T, P>& rhs) noexcept | ||||
| { | ||||
|     return !!rhs.ptr(); | ||||
| } | ||||
|  | ||||
| template<class A> | ||||
| inline void | ||||
| sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p, std::size_t, | ||||
|     std::false_type) | ||||
| { | ||||
|     boost::alloc_destroy(a, boost::to_address(p)); | ||||
| } | ||||
|  | ||||
| template<class A> | ||||
| inline void | ||||
| sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p, | ||||
|     std::size_t n, std::true_type) | ||||
| { | ||||
| #if defined(BOOST_MSVC) && BOOST_MSVC < 1800 | ||||
|     if (!p) { | ||||
|         return; | ||||
|     } | ||||
| #endif | ||||
|     boost::alloc_destroy_n(a, boost::first_scalar(boost::to_address(p)), | ||||
|         n * sp_alloc_size<typename A::value_type>::value); | ||||
| } | ||||
|  | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| class alloc_deleter | ||||
|     : empty_value<typename allocator_rebind<A, | ||||
|         typename detail::sp_alloc_value<T>::type>::type> { | ||||
|     typedef typename allocator_rebind<A, | ||||
|         typename detail::sp_alloc_value<T>::type>::type allocator; | ||||
|     typedef empty_value<allocator> base; | ||||
|  | ||||
| public: | ||||
|     typedef detail::sp_alloc_ptr<T, | ||||
|         typename allocator_pointer<allocator>::type> pointer; | ||||
|  | ||||
|     explicit alloc_deleter(const allocator& a) noexcept | ||||
|         : base(empty_init_t(), a) { } | ||||
|  | ||||
|     void operator()(pointer p) { | ||||
|         detail::sp_alloc_clear(base::get(), p.ptr(), p.size(), std::is_array<T>()); | ||||
|         base::get().deallocate(p.ptr(), p.size()); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template<class T, class A> | ||||
| using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A> >; | ||||
|  | ||||
| namespace detail { | ||||
|  | ||||
| template<class T, class A> | ||||
| class sp_alloc_make { | ||||
| public: | ||||
|     typedef typename boost::allocator_rebind<A, | ||||
|         typename sp_alloc_value<T>::type>::type allocator; | ||||
|  | ||||
| private: | ||||
|     typedef boost::alloc_deleter<T, A> deleter; | ||||
|  | ||||
| public: | ||||
|     typedef std::unique_ptr<typename sp_alloc_result<T>::type, deleter> type; | ||||
|  | ||||
|     sp_alloc_make(const A& a, std::size_t n) | ||||
|         : a_(a) | ||||
|         , n_(n) | ||||
|         , p_(a_.allocate(n)) { } | ||||
|  | ||||
|     ~sp_alloc_make() { | ||||
|         if (p_) { | ||||
|             a_.deallocate(p_, n_); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     typename allocator::value_type* get() const noexcept { | ||||
|         return boost::to_address(p_); | ||||
|     } | ||||
|  | ||||
|     allocator& state() noexcept { | ||||
|         return a_; | ||||
|     } | ||||
|  | ||||
|     type release() noexcept { | ||||
|         pointer p = p_; | ||||
|         p_ = pointer(); | ||||
|         return type(typename deleter::pointer(n_, p), deleter(a_)); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     typedef typename boost::allocator_pointer<allocator>::type pointer; | ||||
|  | ||||
|     allocator a_; | ||||
|     std::size_t n_; | ||||
|     pointer p_; | ||||
| }; | ||||
|  | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<!std::is_array<T>::value, | ||||
|     std::unique_ptr<T, alloc_deleter<T, A> > >::type | ||||
| allocate_unique(const A& alloc) | ||||
| { | ||||
|     detail::sp_alloc_make<T, A> c(alloc, 1); | ||||
|     boost::alloc_construct(c.state(), c.get()); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class A, class... Args> | ||||
| inline typename std::enable_if<!std::is_array<T>::value, | ||||
|     std::unique_ptr<T, alloc_deleter<T, A> > >::type | ||||
| allocate_unique(const A& alloc, Args&&... args) | ||||
| { | ||||
|     detail::sp_alloc_make<T, A> c(alloc, 1); | ||||
|     boost::alloc_construct(c.state(), c.get(), std::forward<Args>(args)...); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<!std::is_array<T>::value, | ||||
|     std::unique_ptr<T, alloc_deleter<T, A> > >::type | ||||
| allocate_unique(const A& alloc, typename detail::sp_type_identity<T>::type&& value) | ||||
| { | ||||
|     detail::sp_alloc_make<T, A> c(alloc, 1); | ||||
|     boost::alloc_construct(c.state(), c.get(), std::move(value)); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<!std::is_array<T>::value, | ||||
|     std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A> > > >::type | ||||
| allocate_unique_noinit(const A& alloc) | ||||
| { | ||||
|     return boost::allocate_unique<T, noinit_adaptor<A> >(alloc); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, | ||||
|     std::unique_ptr<T, alloc_deleter<T, A> > >::type | ||||
| allocate_unique(const A& alloc, std::size_t size) | ||||
| { | ||||
|     detail::sp_alloc_make<T, A> c(alloc, size); | ||||
|     boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()), | ||||
|         size * detail::sp_alloc_size<T>::value); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, | ||||
|     std::unique_ptr<typename detail::sp_alloc_result<T>::type, | ||||
|         alloc_deleter<T, A> > >::type | ||||
| allocate_unique(const A& alloc) | ||||
| { | ||||
|     detail::sp_alloc_make<T, A> c(alloc, std::extent<T>::value); | ||||
|     boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()), | ||||
|         detail::sp_alloc_size<T>::value); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, | ||||
|     std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A> > > >::type | ||||
| allocate_unique_noinit(const A& alloc, std::size_t size) | ||||
| { | ||||
|     return boost::allocate_unique<T, noinit_adaptor<A> >(alloc, size); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, | ||||
|     std::unique_ptr<typename detail::sp_alloc_result<T>::type, | ||||
|         alloc_deleter<T, noinit_adaptor<A> > > >::type | ||||
| allocate_unique_noinit(const A& alloc) | ||||
| { | ||||
|     return boost::allocate_unique<T, noinit_adaptor<A> >(alloc); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, | ||||
|     std::unique_ptr<T, alloc_deleter<T, A> > >::type | ||||
| allocate_unique(const A& alloc, std::size_t size, | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     detail::sp_alloc_make<T, A> c(alloc, size); | ||||
|     boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()), | ||||
|         size * detail::sp_alloc_size<T>::value, boost::first_scalar(&value), | ||||
|         detail::sp_alloc_size<typename std::remove_extent<T>::type>::value); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, | ||||
|     std::unique_ptr<typename detail::sp_alloc_result<T>::type, | ||||
|         alloc_deleter<T, A> > >::type | ||||
| allocate_unique(const A& alloc, | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     detail::sp_alloc_make<T, A> c(alloc, std::extent<T>::value); | ||||
|     boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()), | ||||
|         detail::sp_alloc_size<T>::value, boost::first_scalar(&value), | ||||
|         detail::sp_alloc_size<typename std::remove_extent<T>::type>::value); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class U, class A> | ||||
| inline typename allocator_pointer<typename allocator_rebind<A, | ||||
|     typename detail::sp_alloc_value<T>::type>::type>::type | ||||
| get_allocator_pointer(const std::unique_ptr<T, | ||||
|     alloc_deleter<U, A> >& p) noexcept | ||||
| { | ||||
|     return p.get().ptr(); | ||||
| } | ||||
|  | ||||
| } /* boost */ | ||||
|  | ||||
| #endif | ||||
| @@ -33,7 +33,7 @@ private: | ||||
|  | ||||
| private: | ||||
|  | ||||
|     bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT | ||||
|     bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) noexcept | ||||
|     { | ||||
|         l_.lock(); | ||||
|  | ||||
| @@ -57,34 +57,16 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR ) | ||||
|  | ||||
|     constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT | ||||
|     constexpr atomic_shared_ptr() noexcept: l_ BOOST_DETAIL_SPINLOCK_INIT | ||||
|     { | ||||
|     } | ||||
|  | ||||
| #else | ||||
|  | ||||
|     atomic_shared_ptr() BOOST_SP_NOEXCEPT | ||||
|     atomic_shared_ptr( shared_ptr<T> p ) noexcept | ||||
|         : p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT | ||||
|     { | ||||
|         boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; | ||||
|         std::memcpy( &l_, &init, sizeof( init ) ); | ||||
|     } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|         : p_( std::move( p ) ) | ||||
| #else | ||||
|         : p_( p ) | ||||
| #endif | ||||
|     { | ||||
|         boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; | ||||
|         std::memcpy( &l_, &init, sizeof( init ) ); | ||||
|     } | ||||
|  | ||||
|     atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT | ||||
|     atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         p_.swap( r ); | ||||
| @@ -92,90 +74,120 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT | ||||
|     constexpr bool is_lock_free() const noexcept | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     shared_ptr<T> load( int = 0 ) const BOOST_SP_NOEXCEPT | ||||
|     shared_ptr<T> load() const noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     operator shared_ptr<T>() const BOOST_SP_NOEXCEPT | ||||
|     template<class M> shared_ptr<T> load( M ) const noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     void store( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT | ||||
|     operator shared_ptr<T>() const noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     void store( shared_ptr<T> r ) noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         p_.swap( r ); | ||||
|     } | ||||
|  | ||||
|     shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT | ||||
|     template<class M> void store( shared_ptr<T> r, M ) noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         p_.swap( r ); | ||||
|     } | ||||
|  | ||||
|     shared_ptr<T> exchange( shared_ptr<T> r ) noexcept | ||||
|     { | ||||
|         { | ||||
|             boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|             p_.swap( r ); | ||||
|         } | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|         return std::move( r ); | ||||
|     } | ||||
|  | ||||
|     template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) noexcept | ||||
|     { | ||||
|         { | ||||
|             boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|             p_.swap( r ); | ||||
|         } | ||||
|  | ||||
|         return std::move( r ); | ||||
|  | ||||
| #else | ||||
|  | ||||
|         return r; | ||||
|  | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT | ||||
|     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, w ); | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT | ||||
|     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, w ); | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT | ||||
|     bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, w ); | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT | ||||
|     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, w ); | ||||
|     } | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, w ); | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) BOOST_SP_NOEXCEPT | ||||
|     bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, w ); | ||||
|     } | ||||
|  | ||||
|     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, std::move( w ) ); | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT | ||||
|     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, std::move( w ) ); | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) BOOST_SP_NOEXCEPT | ||||
|     bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, std::move( w ) ); | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT | ||||
|     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, std::move( w ) ); | ||||
|     } | ||||
|  | ||||
| #endif | ||||
|     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, std::move( w ) ); | ||||
|     } | ||||
|  | ||||
|     bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, std::move( w ) ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace boost | ||||
|   | ||||
| @@ -20,23 +20,9 @@ | ||||
| #include <boost/config.hpp> | ||||
| #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 | ||||
|  | ||||
| #if defined(BOOST_CLANG) | ||||
| // Intel C++ on Mac defines __clang__ but doesn't support the pragma | ||||
| # pragma clang diagnostic push | ||||
| @@ -47,7 +33,7 @@ class bad_weak_ptr: public std::exception | ||||
| { | ||||
| public: | ||||
|  | ||||
|     virtual char const * what() const throw() | ||||
|     char const * what() const noexcept override | ||||
|     { | ||||
|         return "tr1::bad_weak_ptr"; | ||||
|     } | ||||
| @@ -57,14 +43,6 @@ public: | ||||
| # pragma clang diagnostic pop | ||||
| #endif | ||||
|  | ||||
| #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 | ||||
|   | ||||
| @@ -43,8 +43,10 @@ | ||||
| //    Memory Ordering: acquire/release | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp> | ||||
| #include <boost/smart_ptr/detail/deprecated_macros.hpp> | ||||
| #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> | ||||
| @@ -73,15 +75,18 @@ | ||||
| #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( BOOST_SP_HAS_GCC_INTRINSICS ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp> | ||||
|  | ||||
| #elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_sync.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> | ||||
|  | ||||
|   | ||||
| @@ -23,6 +23,13 @@ | ||||
| # include <bits/atomicity.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using libstdc++ atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
|   | ||||
							
								
								
									
										63
									
								
								include/boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								include/boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED | ||||
|  | ||||
| // boost/detail/atomic_count_gcc_atomic.hpp | ||||
| // | ||||
| // atomic_count for g++ 4.7+ | ||||
| // | ||||
| // Copyright 2007, 2020 Peter Dimov | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/cstdint.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using __atomic atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class atomic_count | ||||
| { | ||||
| public: | ||||
|  | ||||
|     explicit atomic_count( long v ): value_( static_cast< boost::int_least32_t >( v ) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     long operator++() | ||||
|     { | ||||
|         return __atomic_add_fetch( &value_, +1, __ATOMIC_ACQ_REL ); | ||||
|     } | ||||
|  | ||||
|     long operator--() | ||||
|     { | ||||
|         return __atomic_add_fetch( &value_, -1, __ATOMIC_ACQ_REL ); | ||||
|     } | ||||
|  | ||||
|     operator long() const | ||||
|     { | ||||
|         return __atomic_load_n( &value_, __ATOMIC_ACQUIRE ); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     atomic_count(atomic_count const &); | ||||
|     atomic_count & operator=(atomic_count const &); | ||||
|  | ||||
|     boost::int_least32_t value_; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED | ||||
| @@ -13,6 +13,17 @@ | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/x86 atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -15,6 +15,13 @@ | ||||
| //  http://www.boost.org/LICENSE_1_0.txt | ||||
| // | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using single-threaded, non-atomic atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -14,6 +14,13 @@ | ||||
| #include <boost/assert.hpp> | ||||
| #include <pthread.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using pthread_mutex atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  The generic pthread_mutex-based implementation sometimes leads to | ||||
| //    inefficiencies. Example: a class with two atomic_count members | ||||
|   | ||||
| @@ -1,59 +0,0 @@ | ||||
| #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 | ||||
| @@ -13,6 +13,13 @@ | ||||
|  | ||||
| #include <boost/smart_ptr/detail/spinlock_pool.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using spinlock-based atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -16,6 +16,13 @@ | ||||
| #include <atomic> | ||||
| #include <cstdint> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using std::atomic atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| @@ -26,7 +33,7 @@ class atomic_count | ||||
| { | ||||
| public: | ||||
|  | ||||
|     explicit atomic_count( long v ): value_( v ) | ||||
|     explicit atomic_count( long v ): value_( static_cast< std::int_least32_t >( v ) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -15,10 +15,19 @@ | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/cstdint.hpp> | ||||
|  | ||||
| #if defined( __ia64__ ) && defined( __INTEL_COMPILER ) | ||||
| # include <ia64intrin.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using __sync atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| @@ -29,7 +38,9 @@ class atomic_count | ||||
| { | ||||
| public: | ||||
|  | ||||
|     explicit atomic_count( long v ) : value_( v ) {} | ||||
|     explicit atomic_count( long v ): value_( static_cast< boost::int_least32_t >( v ) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     long operator++() | ||||
|     { | ||||
| @@ -51,7 +62,7 @@ private: | ||||
|     atomic_count(atomic_count const &); | ||||
|     atomic_count & operator=(atomic_count const &); | ||||
|  | ||||
|     mutable long value_; | ||||
|     mutable boost::int_least32_t value_; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|   | ||||
| @@ -19,6 +19,13 @@ | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_interlocked.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using Win32 atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
|   | ||||
							
								
								
									
										52
									
								
								include/boost/smart_ptr/detail/deprecated_macros.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								include/boost/smart_ptr/detail/deprecated_macros.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED | ||||
|  | ||||
| // Copyright 2024 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_ENABLE_DEBUG_HOOKS has been deprecated in 1.87 and support for it was removed in 1.90.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_USE_STD_ALLOCATOR) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_STD_ALLOCATOR has been deprecated in 1.87 and support for it was removed in 1.90.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_QUICK_ALLOCATOR has been deprecated in 1.87 and support for it was removed in 1.90.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_AC_USE_SPINLOCK) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_SPINLOCK has been deprecated in 1.87 and support for it will be removed.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_AC_USE_PTHREADS) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_PTHREADS has been deprecated in 1.87 and support for it will be removed.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_USE_SPINLOCK) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_SPINLOCK has been deprecated in 1.87 and support for it will be removed.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_USE_PTHREADS) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_PTHREADS has been deprecated in 1.87 and support for it will be removed.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED | ||||
| @@ -28,15 +28,12 @@ | ||||
|  | ||||
| #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__) | ||||
| #if !defined(BOOST_NO_CXX11_HDR_MUTEX ) | ||||
| #  include <boost/smart_ptr/detail/lwm_std_mutex.hpp> | ||||
| #elif 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 | ||||
| #  include <boost/smart_ptr/detail/lwm_pthreads.hpp> | ||||
| #endif | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED | ||||
|   | ||||
							
								
								
									
										164
									
								
								include/boost/smart_ptr/detail/lightweight_thread.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								include/boost/smart_ptr/detail/lightweight_thread.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_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, 2018 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 /*...*/ lw_thread_t; // as pthread_t | ||||
| //  template<class F> int lw_thread_create( lw_thread_t & th, F f ); | ||||
| //  void lw_thread_join( lw_thread_t th ); | ||||
|  | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <memory> | ||||
| #include <cerrno> | ||||
|  | ||||
| #if defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
| #include <pthread.h> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| typedef ::pthread_t lw_thread_t; | ||||
|  | ||||
| inline int lw_thread_create_( lw_thread_t* thread, const pthread_attr_t* attr, void* (*start_routine)( void* ), void* arg ) | ||||
| { | ||||
|     return ::pthread_create( thread, attr, start_routine, arg ); | ||||
| } | ||||
|  | ||||
| inline void lw_thread_join( lw_thread_t th ) | ||||
| { | ||||
|     ::pthread_join( th, 0 ); | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #else // defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
| #include <windows.h> | ||||
| #include <process.h> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| typedef HANDLE lw_thread_t; | ||||
|  | ||||
| inline int lw_thread_create_( lw_thread_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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline void lw_thread_join( lw_thread_t thread ) | ||||
| { | ||||
|     ::WaitForSingleObject( thread, INFINITE ); | ||||
|     ::CloseHandle( thread ); | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class lw_abstract_thread | ||||
| { | ||||
| public: | ||||
|  | ||||
|     virtual ~lw_abstract_thread() {} | ||||
|     virtual void run() = 0; | ||||
| }; | ||||
|  | ||||
| #if defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
| extern "C" inline void * lw_thread_routine( void * pv ) | ||||
| { | ||||
|     std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) ); | ||||
|  | ||||
|     pt->run(); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| inline unsigned __stdcall lw_thread_routine( void * pv ) | ||||
| { | ||||
|     std::unique_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( lw_thread_t & th, F f ) | ||||
| { | ||||
|     std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) ); | ||||
|  | ||||
|     int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() ); | ||||
|  | ||||
|     if( r == 0 ) | ||||
|     { | ||||
|         p.release(); | ||||
|     } | ||||
|  | ||||
|     return r; | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED | ||||
| @@ -27,7 +27,7 @@ namespace boost | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class local_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE local_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -42,36 +42,38 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     BOOST_CONSTEXPR local_counted_base() BOOST_SP_NOEXCEPT: local_use_count_( initial_ ) | ||||
|     constexpr local_counted_base() noexcept: local_use_count_( initial_ ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     BOOST_CONSTEXPR local_counted_base( local_counted_base const & ) BOOST_SP_NOEXCEPT: local_use_count_( initial_ ) | ||||
|     constexpr local_counted_base( local_counted_base const & ) noexcept: local_use_count_( initial_ ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual ~local_counted_base() /*BOOST_SP_NOEXCEPT*/ | ||||
|     virtual ~local_counted_base() /*noexcept*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual void local_cb_destroy() noexcept = 0; | ||||
|  | ||||
|     virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual boost::detail::shared_count local_cb_get_shared_count() const noexcept = 0; | ||||
|  | ||||
|     void add_ref() BOOST_SP_NOEXCEPT | ||||
|     void add_ref() noexcept | ||||
|     { | ||||
| #if !defined(__NVCC__) | ||||
| #if defined( __has_builtin ) | ||||
| # if __has_builtin( __builtin_assume ) | ||||
|  | ||||
|         __builtin_assume( local_use_count_ >= 1 ); | ||||
|  | ||||
| # endif | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
|         local_use_count_ = static_cast<count_type>( local_use_count_ + 1 ); | ||||
|     } | ||||
|  | ||||
|     void release() BOOST_SP_NOEXCEPT | ||||
|     void release() noexcept | ||||
|     { | ||||
|         local_use_count_ = static_cast<count_type>( local_use_count_ - 1 ); | ||||
|  | ||||
| @@ -81,13 +83,13 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long local_use_count() const BOOST_SP_NOEXCEPT | ||||
|     long local_use_count() const noexcept | ||||
|     { | ||||
|         return local_use_count_; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class local_counted_impl: public local_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE local_counted_impl: public local_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -99,41 +101,37 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     explicit local_counted_impl( shared_count const& pn ): pn_( pn ) | ||||
|     explicit local_counted_impl( shared_count const& pn ) noexcept: pn_( pn ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|  | ||||
|     explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) ) | ||||
|     explicit local_counted_impl( shared_count && pn ) noexcept: pn_( std::move(pn) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     virtual void local_cb_destroy() BOOST_SP_NOEXCEPT | ||||
|     void local_cb_destroy() noexcept override | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT | ||||
|     boost::detail::shared_count local_cb_get_shared_count() const noexcept override | ||||
|     { | ||||
|         return pn_; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class local_counted_impl_em: public local_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE local_counted_impl_em: public local_counted_base | ||||
| { | ||||
| public: | ||||
|  | ||||
|     shared_count pn_; | ||||
|  | ||||
|     virtual void local_cb_destroy() BOOST_SP_NOEXCEPT | ||||
|     void local_cb_destroy() noexcept override | ||||
|     { | ||||
|         shared_count().swap( pn_ ); | ||||
|     } | ||||
|  | ||||
|     virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT | ||||
|     boost::detail::shared_count local_cb_get_shared_count() const noexcept override | ||||
|     { | ||||
|         return pn_; | ||||
|     } | ||||
|   | ||||
| @@ -38,48 +38,40 @@ public: | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     explicit local_sp_deleter( D const& d ) BOOST_SP_NOEXCEPT: d_( d ) | ||||
|     explicit local_sp_deleter( D const& d ) noexcept: d_( d ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|  | ||||
|     explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) ) | ||||
|     explicit local_sp_deleter( D&& d ) noexcept: d_( std::move(d) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     D& deleter() | ||||
|     D& deleter() noexcept | ||||
|     { | ||||
|         return d_; | ||||
|     } | ||||
|  | ||||
|     template<class Y> void operator()( Y* p ) BOOST_SP_NOEXCEPT | ||||
|     template<class Y> void operator()( Y* p ) noexcept | ||||
|     { | ||||
|         d_( p ); | ||||
|     } | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_NULLPTR ) | ||||
|  | ||||
|     void operator()( boost::detail::sp_nullptr_t p ) BOOST_SP_NOEXCEPT | ||||
|     void operator()( std::nullptr_t p ) noexcept | ||||
|     { | ||||
|         d_( p ); | ||||
|     } | ||||
|  | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| template<> class local_sp_deleter<void> | ||||
| { | ||||
| }; | ||||
|  | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept | ||||
| { | ||||
|     return &p->deleter(); | ||||
| } | ||||
|  | ||||
| inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) | ||||
| inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) noexcept | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -1,37 +0,0 @@ | ||||
| #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 | ||||
							
								
								
									
										62
									
								
								include/boost/smart_ptr/detail/lwm_std_mutex.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								include/boost/smart_ptr/detail/lwm_std_mutex.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED | ||||
|  | ||||
| // Copyright 2020 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| #include <boost/assert.hpp> | ||||
| #include <mutex> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class lightweight_mutex | ||||
| { | ||||
| private: | ||||
|  | ||||
|     std::mutex m_; | ||||
|  | ||||
|     lightweight_mutex(lightweight_mutex const &); | ||||
|     lightweight_mutex & operator=(lightweight_mutex const &); | ||||
|  | ||||
| public: | ||||
|  | ||||
|     lightweight_mutex() | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     class scoped_lock; | ||||
|     friend class scoped_lock; | ||||
|  | ||||
|     class scoped_lock | ||||
|     { | ||||
|     private: | ||||
|  | ||||
|         std::mutex & m_; | ||||
|  | ||||
|         scoped_lock(scoped_lock const &); | ||||
|         scoped_lock & operator=(scoped_lock const &); | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         scoped_lock( lightweight_mutex & m ): m_( m.m_ ) | ||||
|         { | ||||
|             m_.lock(); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         { | ||||
|             m_.unlock(); | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED | ||||
| @@ -11,15 +11,12 @@ | ||||
| //  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> | ||||
| @@ -52,19 +49,24 @@ struct critical_section | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| #if BOOST_PLAT_WINDOWS_RUNTIME | ||||
| extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long); | ||||
| #else | ||||
| extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *); | ||||
| #endif | ||||
| extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *); | ||||
| extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *); | ||||
| extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *); | ||||
|  | ||||
| #else | ||||
| typedef ::_RTL_CRITICAL_SECTION rtl_critical_section; | ||||
|  | ||||
| #else // #ifndef BOOST_USE_WINDOWS_H | ||||
|  | ||||
| typedef ::CRITICAL_SECTION critical_section; | ||||
|  | ||||
| using ::InitializeCriticalSection; | ||||
| using ::EnterCriticalSection; | ||||
| using ::LeaveCriticalSection; | ||||
| using ::DeleteCriticalSection; | ||||
|  | ||||
| typedef ::CRITICAL_SECTION rtl_critical_section; | ||||
|  | ||||
| #endif // #ifndef BOOST_USE_WINDOWS_H | ||||
|  | ||||
| class lightweight_mutex | ||||
| @@ -80,16 +82,12 @@ public: | ||||
|  | ||||
|     lightweight_mutex() | ||||
|     { | ||||
| #if BOOST_PLAT_WINDOWS_RUNTIME | ||||
|         boost::detail::InitializeCriticalSectionEx(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_), 4000, 0); | ||||
| #else | ||||
|         boost::detail::InitializeCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_)); | ||||
| #endif | ||||
|         boost::detail::InitializeCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_)); | ||||
|     } | ||||
|  | ||||
|     ~lightweight_mutex() | ||||
|     { | ||||
|         boost::detail::DeleteCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_)); | ||||
|         boost::detail::DeleteCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_)); | ||||
|     } | ||||
|  | ||||
|     class scoped_lock; | ||||
| @@ -108,12 +106,12 @@ public: | ||||
|  | ||||
|         explicit scoped_lock(lightweight_mutex & m): m_(m) | ||||
|         { | ||||
|             boost::detail::EnterCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_.cs_)); | ||||
|             boost::detail::EnterCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_)); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         { | ||||
|             boost::detail::LeaveCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_.cs_)); | ||||
|             boost::detail::LeaveCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_)); | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
|   | ||||
| @@ -1,64 +0,0 @@ | ||||
| //  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_SP_NOEXCEPT | ||||
|     { | ||||
|         return px != 0; | ||||
|     } | ||||
|  | ||||
| #elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) | ||||
|  | ||||
|     operator bool () const BOOST_SP_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_SP_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_SP_NOEXCEPT | ||||
|     { | ||||
|         return px == 0? 0: &this_type::get; | ||||
|     } | ||||
|  | ||||
| #else | ||||
|  | ||||
|     typedef element_type * this_type::*unspecified_bool_type; | ||||
|  | ||||
|     operator unspecified_bool_type() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return px == 0? 0: &this_type::px; | ||||
|     } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     // operator! is redundant, but some compilers need it | ||||
|     bool operator! () const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return px == 0; | ||||
|     } | ||||
| @@ -1,199 +1,63 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
| // Copyright 2003 David Abrahams | ||||
| // Copyright 2003, 2025 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
| #include <boost/config/header_deprecated.hpp> | ||||
| #include <memory> | ||||
| #include <cstddef> | ||||
|  | ||||
| // | ||||
| //  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 | ||||
| BOOST_HEADER_DEPRECATED("std::allocator or std::pmr::synchronized_pool_resource") | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| template<unsigned size, unsigned align_> union freeblock | ||||
| template<class T> struct quick_allocator | ||||
| { | ||||
|     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 void* alloc() | ||||
|     { | ||||
|         static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm; | ||||
|         static lightweight_mutex * pm = new( &fbm ) lightweight_mutex; | ||||
|         return *pm; | ||||
|         return std::allocator<T>().allocate( 1 ); | ||||
|     } | ||||
|  | ||||
|     static lightweight_mutex * mutex_init; | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     static block * free; | ||||
|     static block * page; | ||||
|     static unsigned last; | ||||
|  | ||||
|     static inline void * alloc() | ||||
|     static void* alloc( std::size_t n ) | ||||
|     { | ||||
| #ifdef BOOST_HAS_THREADS | ||||
|         lightweight_mutex::scoped_lock lock( mutex() ); | ||||
| #endif | ||||
|         if(block * x = free) | ||||
|         if( n != sizeof(T) ) // class-specific delete called for a derived object | ||||
|         { | ||||
|             free = x->next; | ||||
|             return x; | ||||
|             return ::operator new( n ); | ||||
|         } | ||||
|         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++]; | ||||
|             return alloc(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static inline void * alloc(std::size_t n) | ||||
|     static void dealloc( void* p ) | ||||
|     { | ||||
|         if(n != size) // class-specific new called for a derived object | ||||
|         if( p != 0 ) // 18.4.1.1/13 | ||||
|         { | ||||
|             return ::operator new(n); | ||||
|             std::allocator<T>().deallocate( static_cast<T*>( p ), 1 ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static void dealloc( void* p, std::size_t n ) | ||||
|     { | ||||
|         if( n != sizeof(T) ) // class-specific delete called for a derived object | ||||
|         { | ||||
|             ::operator delete( p ); | ||||
|         } | ||||
|         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++]; | ||||
|             } | ||||
|             dealloc( p ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     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 | ||||
|   | ||||
| @@ -18,31 +18,25 @@ | ||||
| // 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 | ||||
| #include <boost/smart_ptr/detail/deprecated_macros.hpp> | ||||
| #include <boost/core/checked_delete.hpp> | ||||
| #include <boost/throw_exception.hpp> | ||||
| #include <boost/core/addressof.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/config/workaround.hpp> | ||||
| #include <boost/cstdint.hpp> | ||||
| #include <memory>            // std::auto_ptr | ||||
| #include <functional>        // std::less | ||||
| #include <cstddef>           // std::size_t | ||||
|  | ||||
| #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" | ||||
| @@ -61,13 +55,6 @@ template< class T, class D > class unique_ptr; | ||||
| 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 | ||||
| @@ -102,6 +89,14 @@ template< class D > struct sp_convert_reference< D& > | ||||
|     typedef sp_reference_wrapper< D > type; | ||||
| }; | ||||
|  | ||||
| template<class T> std::size_t sp_hash_pointer( T* p ) noexcept | ||||
| { | ||||
|     boost::uintptr_t v = reinterpret_cast<boost::uintptr_t>( p ); | ||||
|  | ||||
|     // match boost::hash<T*> | ||||
|     return static_cast<std::size_t>( v + ( v >> 3 ) ); | ||||
| } | ||||
|  | ||||
| class weak_count; | ||||
|  | ||||
| class shared_count | ||||
| @@ -110,32 +105,19 @@ private: | ||||
|  | ||||
|     sp_counted_base * pi_; | ||||
|  | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|     int id_; | ||||
| #endif | ||||
|  | ||||
|     friend class weak_count; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     BOOST_CONSTEXPR shared_count(): pi_(0) // nothrow | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(shared_count_id) | ||||
| #endif | ||||
|     constexpr shared_count() noexcept: pi_(0) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     BOOST_CONSTEXPR explicit shared_count( sp_counted_base * pi ): pi_( pi ) // nothrow | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(shared_count_id) | ||||
| #endif | ||||
|     constexpr explicit shared_count( sp_counted_base * pi ) noexcept: pi_( pi ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     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 | ||||
|  | ||||
| @@ -162,18 +144,8 @@ public: | ||||
| #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 | ||||
| @@ -199,12 +171,7 @@ public: | ||||
| #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 | ||||
|  | ||||
| @@ -231,25 +198,12 @@ public: | ||||
| #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 | ||||
| @@ -288,25 +242,12 @@ public: | ||||
| #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 | ||||
| @@ -345,17 +286,12 @@ public: | ||||
| #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 | ||||
|  | ||||
| @@ -371,17 +307,12 @@ public: | ||||
|  | ||||
| #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() ); | ||||
|         D2 d2( static_cast<D&&>( r.get_deleter() ) ); | ||||
|         pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 ); | ||||
|  | ||||
| #ifdef BOOST_NO_EXCEPTIONS | ||||
| @@ -396,13 +327,8 @@ public: | ||||
|         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; | ||||
|  | ||||
| @@ -421,38 +347,25 @@ public: | ||||
|         r.release(); | ||||
|     } | ||||
|  | ||||
|     ~shared_count() // nothrow | ||||
|     ~shared_count() /*noexcept*/ | ||||
|     { | ||||
|         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 | ||||
|     shared_count(shared_count const & r) noexcept: pi_(r.pi_) | ||||
|     { | ||||
|         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 | ||||
|     shared_count(shared_count && r) noexcept: pi_(r.pi_) | ||||
|     { | ||||
|         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( weak_count const & r, sp_nothrow_tag ) noexcept; // constructs an empty *this when r.use_count() == 0 | ||||
|  | ||||
|     shared_count & operator= (shared_count const & r) // nothrow | ||||
|     shared_count & operator= (shared_count const & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -466,52 +379,61 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     void swap(shared_count & r) // nothrow | ||||
|     void swap(shared_count & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|         r.pi_ = pi_; | ||||
|         pi_ = tmp; | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const noexcept | ||||
|     { | ||||
|         return pi_ != 0? pi_->use_count(): 0; | ||||
|     } | ||||
|  | ||||
|     bool unique() const // nothrow | ||||
|     bool unique() const noexcept | ||||
|     { | ||||
|         return use_count() == 1; | ||||
|     } | ||||
|  | ||||
|     bool empty() const // nothrow | ||||
|     bool empty() const noexcept | ||||
|     { | ||||
|         return pi_ == 0; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator==(shared_count const & a, shared_count const & b) | ||||
|     bool operator==( shared_count const & r ) const noexcept | ||||
|     { | ||||
|         return a.pi_ == b.pi_; | ||||
|         return pi_ == r.pi_; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator<(shared_count const & a, shared_count const & b) | ||||
|     bool operator==( weak_count const & r ) const noexcept; | ||||
|  | ||||
|     bool operator<( shared_count const & r ) const noexcept | ||||
|     { | ||||
|         return std::less<sp_counted_base *>()( a.pi_, b.pi_ ); | ||||
|         return std::less<sp_counted_base *>()( pi_, r.pi_ ); | ||||
|     } | ||||
|  | ||||
|     void * get_deleter( sp_typeinfo const & ti ) const | ||||
|     bool operator<( weak_count const & r ) const noexcept; | ||||
|  | ||||
|     void * get_deleter( sp_typeinfo_ const & ti ) const noexcept | ||||
|     { | ||||
|         return pi_? pi_->get_deleter( ti ): 0; | ||||
|     } | ||||
|  | ||||
|     void * get_local_deleter( sp_typeinfo const & ti ) const | ||||
|     void * get_local_deleter( sp_typeinfo_ const & ti ) const noexcept | ||||
|     { | ||||
|         return pi_? pi_->get_local_deleter( ti ): 0; | ||||
|     } | ||||
|  | ||||
|     void * get_untyped_deleter() const | ||||
|     void * get_untyped_deleter() const noexcept | ||||
|     { | ||||
|         return pi_? pi_->get_untyped_deleter(): 0; | ||||
|     } | ||||
|  | ||||
|     std::size_t hash_value() const noexcept | ||||
|     { | ||||
|         return sp_hash_pointer( pi_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -521,60 +443,37 @@ private: | ||||
|  | ||||
|     sp_counted_base * pi_; | ||||
|  | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|     int id_; | ||||
| #endif | ||||
|  | ||||
|     friend class shared_count; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     BOOST_CONSTEXPR weak_count(): pi_(0) // nothrow | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(weak_count_id) | ||||
| #endif | ||||
|     constexpr weak_count() noexcept: pi_(0) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     weak_count(shared_count const & r): pi_(r.pi_) // nothrow | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(weak_count_id) | ||||
| #endif | ||||
|     weak_count(shared_count const & r) noexcept: pi_(r.pi_) | ||||
|     { | ||||
|         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 | ||||
|     weak_count(weak_count const & r) noexcept: pi_(r.pi_) | ||||
|     { | ||||
|         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 | ||||
|     weak_count(weak_count && r) noexcept: pi_(r.pi_) | ||||
|     { | ||||
|         r.pi_ = 0; | ||||
|     } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     ~weak_count() // nothrow | ||||
|     ~weak_count() /*noexcept*/ | ||||
|     { | ||||
|         if(pi_ != 0) pi_->weak_release(); | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         id_ = 0; | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     weak_count & operator= (shared_count const & r) // nothrow | ||||
|     weak_count & operator= (shared_count const & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -588,7 +487,7 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     weak_count & operator= (weak_count const & r) // nothrow | ||||
|     weak_count & operator= (weak_count const & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -602,38 +501,50 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     void swap(weak_count & r) // nothrow | ||||
|     void swap(weak_count & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|         r.pi_ = pi_; | ||||
|         pi_ = tmp; | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const noexcept | ||||
|     { | ||||
|         return pi_ != 0? pi_->use_count(): 0; | ||||
|     } | ||||
|  | ||||
|     bool empty() const // nothrow | ||||
|     bool empty() const noexcept | ||||
|     { | ||||
|         return pi_ == 0; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator==(weak_count const & a, weak_count const & b) | ||||
|     bool operator==( weak_count const & r ) const noexcept | ||||
|     { | ||||
|         return a.pi_ == b.pi_; | ||||
|         return pi_ == r.pi_; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator<(weak_count const & a, weak_count const & b) | ||||
|     bool operator==( shared_count const & r ) const noexcept | ||||
|     { | ||||
|         return std::less<sp_counted_base *>()(a.pi_, b.pi_); | ||||
|         return pi_ == r.pi_; | ||||
|     } | ||||
|  | ||||
|     bool operator<( weak_count const & r ) const noexcept | ||||
|     { | ||||
|         return std::less<sp_counted_base *>()( pi_, r.pi_ ); | ||||
|     } | ||||
|  | ||||
|     bool operator<( shared_count const & r ) const noexcept | ||||
|     { | ||||
|         return std::less<sp_counted_base *>()( pi_, r.pi_ ); | ||||
|     } | ||||
|  | ||||
|     std::size_t hash_value() const noexcept | ||||
|     { | ||||
|         return sp_hash_pointer( 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() ) | ||||
|     { | ||||
| @@ -641,10 +552,7 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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 | ||||
| inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) noexcept: pi_( r.pi_ ) | ||||
| { | ||||
|     if( pi_ != 0 && !pi_->add_ref_lock() ) | ||||
|     { | ||||
| @@ -652,6 +560,16 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline bool shared_count::operator==( weak_count const & r ) const noexcept | ||||
| { | ||||
|     return pi_ == r.pi_; | ||||
| } | ||||
|  | ||||
| inline bool shared_count::operator<( weak_count const & r ) const noexcept | ||||
| { | ||||
|     return std::less<sp_counted_base *>()( pi_, r.pi_ ); | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
| @@ -660,8 +578,4 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( | ||||
| #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 | ||||
|   | ||||
| @@ -18,20 +18,6 @@ | ||||
| #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 | ||||
| { | ||||
|  | ||||
| @@ -87,6 +73,4 @@ template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_i | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE ) | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED | ||||
|   | ||||
| @@ -17,14 +17,10 @@ | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp> | ||||
| #include <boost/smart_ptr/detail/deprecated_macros.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_has_sync.hpp> | ||||
|  | ||||
| #if !defined( __c2__ ) && 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> | ||||
| @@ -41,18 +37,24 @@ | ||||
| #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( BOOST_SP_HAS_GCC_INTRINSICS ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp> | ||||
|  | ||||
| #elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp> | ||||
|  | ||||
| #elif defined( __SNC__ ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp> | ||||
| #elif defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_sync.hpp> | ||||
|  | ||||
| #elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_sync.hpp> | ||||
|  | ||||
| #elif defined( __SNC__ ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp> | ||||
|  | ||||
| #elif defined(__HP_aCC) && defined(__ia64) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp> | ||||
|  | ||||
| @@ -71,9 +73,6 @@ | ||||
| #elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 ) | ||||
| # 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> | ||||
|  | ||||
| @@ -91,6 +90,4 @@ | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #undef BOOST_SP_HAS_CLANG_C11_ATOMICS | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED | ||||
|   | ||||
| @@ -15,9 +15,20 @@ | ||||
| //  Lock-free algorithm by Alexander Terekhov | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <machine/sys/inline.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using HP aCC++/HP-UX/IA64 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| @@ -71,7 +82,7 @@ inline int atomic_conditional_increment( int * pw ) | ||||
|     } | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -103,8 +114,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -20,10 +20,18 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <builtins.h> | ||||
| #include <sys/atomic_op.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using AIX sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| @@ -63,7 +71,7 @@ inline int32_t atomic_conditional_increment( int32_t * pw ) | ||||
|     } | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -95,8 +103,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -1,150 +0,0 @@ | ||||
| #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; | ||||
|         } | ||||
|     }     | ||||
| } | ||||
|  | ||||
| #if defined(__clang__) | ||||
| # pragma clang diagnostic push | ||||
| # pragma clang diagnostic ignored "-Wweak-vtables" | ||||
| #endif | ||||
|  | ||||
| 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_local_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 ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| #if defined(__clang__) | ||||
| # pragma clang diagnostic pop | ||||
| #endif | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED | ||||
| @@ -24,7 +24,16 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using CodeWarrior/PowerPC sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -53,7 +62,11 @@ inline long atomic_decrement( register long * pw ) | ||||
|  | ||||
|     asm | ||||
|     { | ||||
| #if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__) | ||||
|     msync | ||||
| #else | ||||
|     sync | ||||
| #endif | ||||
|  | ||||
| loop: | ||||
|  | ||||
| @@ -91,7 +104,7 @@ store: | ||||
|     return a; | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -123,8 +136,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -1,160 +0,0 @@ | ||||
| #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_local_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 | ||||
							
								
								
									
										148
									
								
								include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // detail/sp_counted_base_gcc_atomic.hpp - g++ 4.7+ __atomic intrinsics | ||||
| // | ||||
| // Copyright 2007, 2020 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/cstdint.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using __atomic sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( boost::uint_least32_t * pw ) | ||||
| { | ||||
|     __atomic_fetch_add( pw, 1, __ATOMIC_RELAXED ); | ||||
| } | ||||
|  | ||||
| inline boost::uint_least32_t atomic_decrement( boost::uint_least32_t * pw ) | ||||
| { | ||||
|     return __atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL ); | ||||
| } | ||||
|  | ||||
| inline boost::uint_least32_t atomic_conditional_increment( boost::uint_least32_t * pw ) | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // if( r != 0 ) ++*pw; | ||||
|     // return r; | ||||
|  | ||||
|     boost::uint_least32_t r = __atomic_load_n( pw, __ATOMIC_RELAXED ); | ||||
|  | ||||
|     for( ;; ) | ||||
|     { | ||||
|         if( r == 0 ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|  | ||||
|         if( __atomic_compare_exchange_n( pw, &r, r + 1, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline boost::uint_least32_t atomic_load( boost::uint_least32_t const * pw ) | ||||
| { | ||||
|     return __atomic_load_n( pw, __ATOMIC_ACQUIRE ); | ||||
| } | ||||
|  | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     sp_counted_base( sp_counted_base const & ); | ||||
|     sp_counted_base & operator= ( sp_counted_base const & ); | ||||
|  | ||||
|     boost::uint_least32_t use_count_;        // #shared | ||||
|     boost::uint_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_local_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 static_cast<long>( atomic_load( &use_count_ ) ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED | ||||
| @@ -16,7 +16,18 @@ | ||||
| //  Lock-free algorithm by Alexander Terekhov | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/IA64 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -78,7 +89,7 @@ inline int atomic_conditional_increment( int * pw ) | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -110,8 +121,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -20,7 +20,18 @@ | ||||
| //  Lock-free algorithm by Alexander Terekhov | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/MIPS sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -38,7 +49,9 @@ inline void atomic_increment( int * pw ) | ||||
|     ( | ||||
|         "0:\n\t" | ||||
|         ".set push\n\t" | ||||
| #if !defined(__mips_isa_rev) || (__mips_isa_rev < 6) | ||||
|         ".set mips2\n\t" | ||||
| #endif | ||||
|         "ll %0, %1\n\t" | ||||
|         "addiu %0, 1\n\t" | ||||
|         "sc %0, %1\n\t" | ||||
| @@ -59,7 +72,9 @@ inline int atomic_decrement( int * pw ) | ||||
|     ( | ||||
|         "0:\n\t" | ||||
|         ".set push\n\t" | ||||
| #if !defined(__mips_isa_rev) || (__mips_isa_rev < 6) | ||||
|         ".set mips2\n\t" | ||||
| #endif | ||||
|         "ll %1, %2\n\t" | ||||
|         "addiu %0, %1, -1\n\t" | ||||
|         "sc %0, %2\n\t" | ||||
| @@ -85,7 +100,9 @@ inline int atomic_conditional_increment( int * pw ) | ||||
|     ( | ||||
|         "0:\n\t" | ||||
|         ".set push\n\t" | ||||
| #if !defined(__mips_isa_rev) || (__mips_isa_rev < 6) | ||||
|         ".set mips2\n\t" | ||||
| #endif | ||||
|         "ll %0, %2\n\t" | ||||
|         "beqz %0, 1f\n\t" | ||||
|         "addiu %1, %0, 1\n\t" | ||||
| @@ -102,7 +119,7 @@ inline int atomic_conditional_increment( int * pw ) | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -134,8 +151,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -24,7 +24,18 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/PowerPC sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -102,7 +113,7 @@ inline int atomic_conditional_increment( int * pw ) | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -134,8 +145,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -19,9 +19,20 @@ | ||||
| // | ||||
| //  Thanks to Michael van der Westhuizen | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <inttypes.h> // int32_t | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/Sparc sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| @@ -87,7 +98,7 @@ inline int32_t atomic_conditional_increment( int32_t * pw ) | ||||
|     }     | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -119,8 +130,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -24,7 +24,18 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/x86 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -94,7 +105,7 @@ inline int atomic_conditional_increment( int * pw ) | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -126,8 +137,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -18,7 +18,16 @@ | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/cstdint.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using single-threaded, non-atomic sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -26,55 +35,55 @@ namespace boost | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE 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) | ||||
|     boost::int_least32_t use_count_;        // #shared | ||||
|     boost::int_least32_t weak_count_;       // #weak + (#shared != 0) | ||||
|  | ||||
| public: | ||||
|  | ||||
|     sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) | ||||
|     sp_counted_base() noexcept: use_count_( 1 ), weak_count_( 1 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() // nothrow | ||||
|     virtual ~sp_counted_base() /*noexcept*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // dispose() is called when use_count_ drops to zero, to release | ||||
|     // the resources managed by *this. | ||||
|  | ||||
|     virtual void dispose() = 0; // nothrow | ||||
|     virtual void dispose() noexcept = 0; // nothrow | ||||
|  | ||||
|     // destroy() is called when weak_count_ drops to zero. | ||||
|  | ||||
|     virtual void destroy() // nothrow | ||||
|     virtual void destroy() noexcept // nothrow | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) noexcept = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept = 0; | ||||
|     virtual void * get_untyped_deleter() noexcept = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|     void add_ref_copy() noexcept | ||||
|     { | ||||
|         ++use_count_; | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() // true on success | ||||
|     bool add_ref_lock() noexcept // true on success | ||||
|     { | ||||
|         if( use_count_ == 0 ) return false; | ||||
|         ++use_count_; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     void release() // nothrow | ||||
|     void release() noexcept | ||||
|     { | ||||
|         if( --use_count_ == 0 ) | ||||
|         { | ||||
| @@ -83,12 +92,12 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     void weak_add_ref() noexcept | ||||
|     { | ||||
|         ++weak_count_; | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     void weak_release() noexcept | ||||
|     { | ||||
|         if( --weak_count_ == 0 ) | ||||
|         { | ||||
| @@ -96,7 +105,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const noexcept | ||||
|     { | ||||
|         return use_count_; | ||||
|     } | ||||
|   | ||||
| @@ -18,25 +18,34 @@ | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/assert.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/cstdint.hpp> | ||||
| #include <pthread.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using pthread_mutex sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE 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) | ||||
|     boost::int_least32_t use_count_;        // #shared | ||||
|     boost::int_least32_t weak_count_;       // #weak + (#shared != 0) | ||||
|  | ||||
|     mutable pthread_mutex_t m_; | ||||
|  | ||||
| @@ -70,8 +79,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
| @@ -92,7 +101,7 @@ public: | ||||
|     void release() // nothrow | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         long new_use_count = --use_count_; | ||||
|         boost::int_least32_t new_use_count = --use_count_; | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|  | ||||
|         if( new_use_count == 0 ) | ||||
| @@ -112,7 +121,7 @@ public: | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         long new_weak_count = --weak_count_; | ||||
|         boost::int_least32_t new_weak_count = --weak_count_; | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|  | ||||
|         if( new_weak_count == 0 ) | ||||
| @@ -124,7 +133,7 @@ public: | ||||
|     long use_count() const // nothrow | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         long r = use_count_; | ||||
|         boost::int_least32_t r = use_count_; | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|  | ||||
|         return r; | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| //  detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+ | ||||
| //  detail/sp_counted_base_gcc_snc_ps3.hpp - PS3 Cell | ||||
| // | ||||
| //  Copyright (c) 2006 Piotr Wyderski | ||||
| //  Copyright (c) 2006 Tomas Puverle | ||||
| @@ -19,9 +19,20 @@ | ||||
| // | ||||
| //  Thanks to Michael van der Westhuizen | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <inttypes.h> // uint32_t | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using PS3 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| @@ -82,7 +93,7 @@ inline uint32_t atomic_conditional_increment( uint32_t * pw ) | ||||
|     }     | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -114,8 +125,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -1,115 +0,0 @@ | ||||
| #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_local_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 | ||||
| @@ -18,8 +18,16 @@ | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/spinlock_pool.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using spinlock-based sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -51,7 +59,7 @@ inline int atomic_conditional_increment( int * pw ) | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -83,8 +91,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -15,27 +15,35 @@ | ||||
| //  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/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <atomic> | ||||
| #include <cstdint> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using std::atomic sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( std::atomic_int_least32_t * pw ) | ||||
| inline void atomic_increment( std::atomic_int_least32_t * pw ) noexcept | ||||
| { | ||||
|     pw->fetch_add( 1, std::memory_order_relaxed ); | ||||
| } | ||||
|  | ||||
| inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) | ||||
| inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) noexcept | ||||
| { | ||||
|     return pw->fetch_sub( 1, std::memory_order_acq_rel ); | ||||
| } | ||||
|  | ||||
| inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) | ||||
| inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) noexcept | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // if( r != 0 ) ++*pw; | ||||
| @@ -57,53 +65,53 @@ inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_ | ||||
|     }     | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE 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) | ||||
|     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 ) | ||||
|     sp_counted_base() noexcept: use_count_( 1 ), weak_count_( 1 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() // nothrow | ||||
|     virtual ~sp_counted_base() /*noexcept*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // dispose() is called when use_count_ drops to zero, to release | ||||
|     // the resources managed by *this. | ||||
|  | ||||
|     virtual void dispose() = 0; // nothrow | ||||
|     virtual void dispose() noexcept = 0; | ||||
|  | ||||
|     // destroy() is called when weak_count_ drops to zero. | ||||
|  | ||||
|     virtual void destroy() // nothrow | ||||
|     virtual void destroy() noexcept | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) noexcept = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept = 0; | ||||
|     virtual void * get_untyped_deleter() noexcept = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|     void add_ref_copy() noexcept | ||||
|     { | ||||
|         atomic_increment( &use_count_ ); | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() // true on success | ||||
|     bool add_ref_lock() noexcept // true on success | ||||
|     { | ||||
|         return atomic_conditional_increment( &use_count_ ) != 0; | ||||
|     } | ||||
|  | ||||
|     void release() // nothrow | ||||
|     void release() noexcept | ||||
|     { | ||||
|         if( atomic_decrement( &use_count_ ) == 1 ) | ||||
|         { | ||||
| @@ -112,12 +120,12 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     void weak_add_ref() noexcept | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     void weak_release() noexcept | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 1 ) | ||||
|         { | ||||
| @@ -125,7 +133,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const noexcept | ||||
|     { | ||||
|         return use_count_.load( std::memory_order_acquire ); | ||||
|     } | ||||
|   | ||||
| @@ -15,13 +15,21 @@ | ||||
| //  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/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <limits.h> | ||||
|  | ||||
| #if defined( __ia64__ ) && defined( __INTEL_COMPILER ) | ||||
| # include <ia64intrin.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using __sync sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| @@ -76,7 +84,7 @@ inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw ) | ||||
|     }     | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -108,8 +116,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -21,7 +21,18 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using xlC/PowerPC sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| extern "builtin" void __lwsync(void); | ||||
| extern "builtin" void __isync(void); | ||||
| @@ -70,7 +81,7 @@ inline int atomic_conditional_increment( int *pw ) | ||||
|    } | ||||
| } | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -103,8 +114,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
|   | ||||
| @@ -25,8 +25,16 @@ | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_interlocked.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config/workaround.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using Win32 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -34,7 +42,7 @@ namespace boost | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class sp_counted_base | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -66,8 +74,8 @@ public: | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|  | ||||
|     void add_ref_copy() | ||||
| @@ -82,18 +90,7 @@ public: | ||||
|             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 | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -18,36 +18,18 @@ | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_counted_base.hpp> | ||||
| #include <boost/smart_ptr/detail/deprecated_macros.hpp> | ||||
| #include <boost/core/checked_delete.hpp> | ||||
| #include <boost/core/addressof.hpp> | ||||
| #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> | ||||
| #include <boost/core/addressof.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 <memory>           // std::allocator, std::allocator_traits | ||||
| #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 | ||||
| { | ||||
|  | ||||
| @@ -55,16 +37,16 @@ namespace detail | ||||
|  | ||||
| template<class D> class local_sp_deleter; | ||||
|  | ||||
| template<class D> D * get_local_deleter( D * /*p*/ ) | ||||
| template<class D> D * get_local_deleter( D * /*p*/ ) noexcept | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ); | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept; | ||||
|  | ||||
| // | ||||
|  | ||||
| template<class X> class sp_counted_impl_p: public sp_counted_base | ||||
| template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
| @@ -79,76 +61,35 @@ 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 | ||||
|     void dispose() noexcept override | ||||
|     { | ||||
| #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 & ) | ||||
|     void * get_deleter( sp_typeinfo_ const & ) noexcept override | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ) | ||||
|     void * get_local_deleter( sp_typeinfo_ const & ) noexcept override | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_untyped_deleter() | ||||
|     void * get_untyped_deleter() noexcept override | ||||
|     { | ||||
|         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 | ||||
| template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     P ptr; // copy constructor must not throw | ||||
|     D del; // copy constructor must not throw | ||||
|     D del; // copy/move constructor must not throw | ||||
|  | ||||
|     sp_counted_impl_pd( sp_counted_impl_pd const & ); | ||||
|     sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); | ||||
| @@ -159,7 +100,7 @@ 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, D & d ): ptr( p ), del( static_cast< D&& >( d ) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| @@ -167,61 +108,33 @@ public: | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() // nothrow | ||||
|     void dispose() noexcept override | ||||
|     { | ||||
|         del( ptr ); | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) | ||||
|     void * get_deleter( sp_typeinfo_ const & ti ) noexcept override | ||||
|     { | ||||
|         return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0; | ||||
|         return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) | ||||
|     void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override | ||||
|     { | ||||
|         return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0; | ||||
|         return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_untyped_deleter() | ||||
|     void * get_untyped_deleter() noexcept override | ||||
|     { | ||||
|         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 | ||||
| template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     P p_; // copy constructor must not throw | ||||
|     D d_; // copy constructor must not throw | ||||
|     D d_; // copy/move constructor must not throw | ||||
|     A a_; // copy constructor must not throw | ||||
|  | ||||
|     sp_counted_impl_pda( sp_counted_impl_pda const & ); | ||||
| @@ -233,7 +146,7 @@ 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, D & d, A a ): p_( p ), d_( static_cast< D&& >( d ) ), a_( a ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| @@ -241,23 +154,15 @@ public: | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() // nothrow | ||||
|     void dispose() noexcept override | ||||
|     { | ||||
|         d_( p_ ); | ||||
|     } | ||||
|  | ||||
|     virtual void destroy() // nothrow | ||||
|     void destroy() noexcept override | ||||
|     { | ||||
| #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_ ); | ||||
|  | ||||
|         this->~this_type(); | ||||
| @@ -265,26 +170,22 @@ public: | ||||
|         a2.deallocate( this, 1 ); | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) | ||||
|     void * get_deleter( sp_typeinfo_ const & ti ) noexcept override | ||||
|     { | ||||
|         return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0; | ||||
|         return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) | ||||
|     void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override | ||||
|     { | ||||
|         return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0; | ||||
|         return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_untyped_deleter() | ||||
|     void * get_untyped_deleter() noexcept override | ||||
|     { | ||||
|         return &reinterpret_cast<char&>( d_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| #ifdef __CODEGUARD__ | ||||
| # pragma option pop | ||||
| #endif | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|   | ||||
							
								
								
									
										37
									
								
								include/boost/smart_ptr/detail/sp_cxx20_constexpr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								include/boost/smart_ptr/detail/sp_cxx20_constexpr.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| #pragma once | ||||
| #endif | ||||
|  | ||||
| //  detail/sp_noexcept.hpp | ||||
| // | ||||
| //  Copyright 2025 Mathias Stearn | ||||
| // | ||||
| //  Distributed under the Boost Software License, Version 1.0. | ||||
| //  See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
|  | ||||
| // This macro is used to mark functions as constexpr if the compiler supports | ||||
| // constexpr destructors. Since you can't have a constexpr smart pointer object, | ||||
| // everything except null constructors are guided behind this macro. Because | ||||
| // this also guards a use of dynamic_cast, we need to check for its availability | ||||
| // as well. It isn't worth splitting out since all known compilers that support | ||||
| // constexpr dynamic_cast also support constexpr destructors. | ||||
| // | ||||
| // WARNING: This does not check for changing active member of a union in | ||||
| // constant expressions which is allowed in C++20. If that is needed, we | ||||
| // need to raise the checked version to 202002L. | ||||
| #if defined(__cpp_constexpr_dynamic_alloc) && __cpp_constexpr_dynamic_alloc >= 201907L \ | ||||
|     && defined(__cpp_constexpr) && __cpp_constexpr >= 201907L | ||||
| #define BOOST_SP_CXX20_CONSTEXPR constexpr | ||||
| #else | ||||
| #define BOOST_SP_CXX20_CONSTEXPR | ||||
| #define BOOST_SP_NO_CXX20_CONSTEXPR | ||||
| #endif | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED | ||||
| @@ -1,52 +0,0 @@ | ||||
| #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 | ||||
							
								
								
									
										30
									
								
								include/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								include/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
|  | ||||
| // boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp | ||||
| // | ||||
| // Copyright 2020 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
| // | ||||
| // Defines the BOOST_SP_HAS_GCC_INTRINSICS macro if the __atomic_* | ||||
| // intrinsics are available. | ||||
|  | ||||
| // Libraries (e.g. Kokkos) sometimes define the __ATOMIC_RELAXED macros, | ||||
| // leading to errors under MSVC (https://github.com/boostorg/smart_ptr/pull/112) | ||||
|  | ||||
| #if defined( __ATOMIC_RELAXED ) && defined( __ATOMIC_ACQUIRE ) && defined( __ATOMIC_RELEASE ) && defined( __ATOMIC_ACQ_REL ) \ | ||||
|     && !( defined(_MSC_VER) && !defined(__clang__) ) | ||||
|  | ||||
| # define BOOST_SP_HAS_GCC_INTRINSICS | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED | ||||
| @@ -1,69 +0,0 @@ | ||||
| #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( __c2__ ) && defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) | ||||
|  | ||||
| # define BOOST_SP_HAS_SYNC | ||||
|  | ||||
| #elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ ) | ||||
|  | ||||
| # define BOOST_SP_HAS_SYNC | ||||
|  | ||||
| #elif !defined( __c2__ ) && 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 | ||||
							
								
								
									
										69
									
								
								include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_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_intrinsics.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_INTRINSICS macro if the __sync_* intrinsics | ||||
| //  are available. | ||||
| // | ||||
|  | ||||
| #if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC ) | ||||
|  | ||||
| #if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) && !defined( __c2__ ) | ||||
|  | ||||
| # define BOOST_SP_HAS_SYNC_INTRINSICS | ||||
|  | ||||
| #elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ ) | ||||
|  | ||||
| # define BOOST_SP_HAS_SYNC_INTRINSICS | ||||
|  | ||||
| #elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __c2__ ) | ||||
|  | ||||
| #define BOOST_SP_HAS_SYNC_INTRINSICS | ||||
|  | ||||
| #if defined( __arm__ )  || defined( __armel__ ) | ||||
| #undef BOOST_SP_HAS_SYNC_INTRINSICS | ||||
| #endif | ||||
|  | ||||
| #if defined( __hppa ) || defined( __hppa__ ) | ||||
| #undef BOOST_SP_HAS_SYNC_INTRINSICS | ||||
| #endif | ||||
|  | ||||
| #if defined( __m68k__ ) | ||||
| #undef BOOST_SP_HAS_SYNC_INTRINSICS | ||||
| #endif | ||||
|  | ||||
| #if defined( __sh__ ) | ||||
| #undef BOOST_SP_HAS_SYNC_INTRINSICS | ||||
| #endif | ||||
|  | ||||
| #if defined( __sparc__ ) | ||||
| #undef BOOST_SP_HAS_SYNC_INTRINSICS | ||||
| #endif | ||||
|  | ||||
| #if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 ) | ||||
| #undef BOOST_SP_HAS_SYNC_INTRINSICS | ||||
| #endif | ||||
|  | ||||
| #if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))  | ||||
| #undef BOOST_SP_HAS_SYNC_INTRINSICS | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // #if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC ) | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user