forked from boostorg/smart_ptr
		
	Compare commits
	
		
			295 Commits
		
	
	
		
			feature/en
			...
			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 | ||
|  | cd562eb053 | 
							
								
								
									
										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 | ||||
							
								
								
									
										288
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										288
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -22,24 +22,48 @@ matrix: | ||||
|     - env: BOGUS_JOB=true | ||||
|  | ||||
|   include: | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc CXXSTD=03,11 | ||||
|  | ||||
|     - os: linux | ||||
|       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 COMPILER=g++ CXXSTD=03,11,14 | ||||
|       env: TOOLSET=gcc CXXSTD=03,11,14 | ||||
|  | ||||
|     - os: linux | ||||
|       arch: ppc64le | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 | ||||
|       env: TOOLSET=gcc CXXSTD=03,11,14 | ||||
|  | ||||
|     - os: linux | ||||
|       arch: s390x | ||||
|       compiler: g++ | ||||
|       env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 | ||||
|       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 COMPILER=g++-4.4 CXXSTD=98,0x | ||||
|       env: TOOLSET=gcc CXXSTD=98,0x | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
| @@ -49,7 +73,7 @@ matrix: | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.6 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x | ||||
|       env: TOOLSET=gcc CXXSTD=03,0x | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
| @@ -58,118 +82,31 @@ matrix: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.7 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11 | ||||
|       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.7 | ||||
|             - g++-10 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-4.8 | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,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=03,11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-5 | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-6 | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-7 | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-8 | ||||
|       env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-8 | ||||
|       env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=17,2a | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-9 | ||||
|       env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-9 | ||||
|       env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=17,2a | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: g++-7 | ||||
|       env: UBSAN=1 TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|             - g++-10 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: /usr/bin/clang++ | ||||
|       env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11 | ||||
|       env: TOOLSET=clang COMMENT=clang-3.3 CXXSTD=03,11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
| @@ -178,147 +115,24 @@ matrix: | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: /usr/bin/clang++ | ||||
|       env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11 | ||||
|       env: TOOLSET=clang COMMENT=clang-3.4 CXXSTD=03,11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.4 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.5 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11 | ||||
|       compiler: clang++-11 | ||||
|       env: UBSAN=1 TOOLSET=clang CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.5 | ||||
|             - clang-11 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.6 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.7 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.8 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.9 | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-4.0 | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-5.0 | ||||
|       env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-5.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-6.0 | ||||
|       env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-6.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-7 | ||||
|       env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-xenial-7 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-8 | ||||
|       env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-xenial-8 | ||||
|  | ||||
|     - os: linux | ||||
|       dist: xenial | ||||
|       compiler: clang++-9 | ||||
|       env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main' | ||||
|             - sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-11 main' | ||||
|               key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-8 | ||||
|       env: UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-xenial-8 | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: clang++-libc++ | ||||
|       env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - libc++-dev | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       compiler: clang++-libc++ | ||||
| @@ -328,9 +142,14 @@ matrix: | ||||
|           packages: | ||||
|             - libc++-dev | ||||
|  | ||||
|     - os: osx | ||||
|       compiler: clang++ | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z | ||||
|     - os: linux | ||||
|       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: | ||||
|             - libc++-dev | ||||
|  | ||||
|     - os: osx | ||||
|       compiler: clang++ | ||||
| @@ -341,6 +160,7 @@ matrix: | ||||
|       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: linux | ||||
| @@ -355,6 +175,7 @@ matrix: | ||||
|     - 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 | ||||
| @@ -386,6 +207,7 @@ install: | ||||
|   - 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 | ||||
| @@ -393,7 +215,7 @@ install: | ||||
|  | ||||
| script: | ||||
|   - |- | ||||
|     echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam | ||||
|     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: | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| # Copyright 2018-2020 Peter Dimov | ||||
| # Generated by `boostdep --cmake smart_ptr` | ||||
| # Copyright 2020, 2021 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||||
| # https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| cmake_minimum_required(VERSION 3.5...3.16) | ||||
| cmake_minimum_required(VERSION 3.8...3.20) | ||||
|  | ||||
| project(boost_smart_ptr VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) | ||||
|  | ||||
| @@ -16,20 +17,12 @@ target_link_libraries(boost_smart_ptr | ||||
|     Boost::assert | ||||
|     Boost::config | ||||
|     Boost::core | ||||
|     Boost::move | ||||
|     Boost::static_assert | ||||
|     Boost::throw_exception | ||||
|     Boost::type_traits | ||||
| ) | ||||
|  | ||||
| if(BOOST_SUPERPROJECT_VERSION) | ||||
| target_compile_features(boost_smart_ptr INTERFACE cxx_std_11) | ||||
|  | ||||
|   include(BoostInstall) | ||||
|   boost_install(TARGETS boost_smart_ptr HEADER_DIRECTORY include/) | ||||
|  | ||||
| endif() | ||||
|  | ||||
| if(BUILD_TESTING) | ||||
| if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") | ||||
|  | ||||
|   add_subdirectory(test) | ||||
|  | ||||
|   | ||||
							
								
								
									
										63
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								appveyor.yml
									
									
									
									
									
								
							| @@ -15,38 +15,48 @@ branches: | ||||
| environment: | ||||
|   matrix: | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       TOOLSET: msvc-12.0,msvc-14.0 | ||||
|       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 2017 | ||||
|       TOOLSET: clang-win | ||||
|       CXXSTD: 14,17 | ||||
|       ADDRMD: 64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|       TOOLSET: msvc-14.2 | ||||
|       CXXSTD: 14,17 | ||||
|       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: 03,11,14,1z | ||||
|       CXXSTD: 11,14,1z | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       ADDPATH: C:\cygwin64\bin; | ||||
|       TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,1z | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       ADDPATH: C:\mingw\bin; | ||||
|       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: 03,11,14,1z | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin; | ||||
|       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: 03,11,14,1z | ||||
|       CXXSTD: 11,14,17 | ||||
|  | ||||
| install: | ||||
|   - set BOOST_BRANCH=develop | ||||
| @@ -54,24 +64,9 @@ install: | ||||
|   - cd .. | ||||
|   - 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/container_hash | ||||
|   - git submodule init libs/core | ||||
|   - git submodule init libs/move | ||||
|   - git submodule init libs/predef | ||||
|   - git submodule init libs/static_assert | ||||
|   - git submodule init libs/throw_exception | ||||
|   - git submodule init libs/type_traits | ||||
|   - git submodule init libs/detail | ||||
|   - git submodule init libs/integer | ||||
|   - git submodule init tools/build | ||||
|   - git submodule init libs/headers | ||||
|   - git submodule init tools/boost_install | ||||
|   - git submodule update --jobs 3 | ||||
|   - 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 -d0 headers | ||||
|  | ||||
| @@ -81,4 +76,4 @@ test_script: | ||||
|   - 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 | ||||
|   - 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 | ||||
|     ; | ||||
| @@ -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,44 +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[] | ||||
| @@ -73,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 | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| //// | ||||
| Copyright 2019 Glen Joseph Fernandes (glenjofe@gmail.com) | ||||
| Copyright 2019-2021 Glen Joseph Fernandes (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
|  | ||||
| @@ -85,6 +85,11 @@ namespace boost { | ||||
|   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; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| @@ -269,6 +274,18 @@ 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` | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| //// | ||||
| Copyright 2019 Peter Dimov | ||||
| Copyright 2019-2025 Peter Dimov | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
|  | ||||
| @@ -13,6 +13,33 @@ http://www.boost.org/LICENSE_1_0.txt | ||||
| :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` | ||||
|   | ||||
| @@ -31,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. | ||||
|  | ||||
| @@ -39,10 +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. | ||||
|   | ||||
| @@ -174,7 +174,8 @@ template<class Y> intrusive_ptr(intrusive_ptr<Y> && r); | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Postconditions:: `get()` equals the old value of `r.get()`. `r.get() == 0`. | ||||
| Postconditions:: | ||||
|   `get()` equals the old value of `r.get()`. `r.get() == 0`. | ||||
|  | ||||
| ### destructor | ||||
|  | ||||
| @@ -185,7 +186,8 @@ Postconditions:: `get()` equals the old value of `r.get()`. `r.get() == 0`. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: `if(get() != 0) intrusive_ptr_release(get());`. | ||||
| Effects:: | ||||
|   `if(get() != 0) intrusive_ptr_release(get());`. | ||||
|  | ||||
| ### assignment | ||||
|  | ||||
| @@ -245,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 | ||||
|  | ||||
| @@ -278,7 +281,8 @@ T * get() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: the stored pointer. | ||||
| Returns:: | ||||
|   the stored pointer. | ||||
|  | ||||
| ### detach | ||||
|  | ||||
| @@ -325,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 | ||||
|  | ||||
| @@ -412,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 | ||||
|  | ||||
| @@ -437,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 | ||||
|  | ||||
| @@ -449,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 | ||||
|  | ||||
| @@ -461,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<< | ||||
|  | ||||
|   | ||||
| @@ -111,7 +111,8 @@ intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Does nothing, reference counter is not modified. | ||||
| Effects:: | ||||
|   Does nothing, reference counter is not modified. | ||||
|  | ||||
| ### use_count | ||||
|  | ||||
| @@ -137,7 +138,8 @@ template<class Derived, class CounterPolicy> | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Increments the reference counter. | ||||
| Effects:: | ||||
|   Increments the reference counter. | ||||
|  | ||||
| ### intrusive_ptr_release | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| ``` | ||||
|   | ||||
| @@ -30,8 +30,8 @@ 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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										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 )`. | ||||
| @@ -210,7 +210,8 @@ T* get() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The stored pointer. | ||||
| Returns:: | ||||
|   The stored pointer. | ||||
|  | ||||
| ### unique | ||||
|  | ||||
| @@ -220,8 +221,8 @@ bool unique() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `true` if no other `shared_array` is sharing ownership of the | ||||
| stored pointer, `false` otherwise. | ||||
| Returns:: | ||||
|   `true` if no other `shared_array` is sharing ownership of the stored pointer, `false` otherwise. | ||||
|  | ||||
| ### use_count | ||||
|  | ||||
| @@ -253,7 +254,8 @@ void swap(shared_array<T>& b) noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Exchanges the contents of the two smart pointers. | ||||
| Effects:: | ||||
|   Exchanges the contents of the two smart pointers. | ||||
|  | ||||
| ## Free Functions | ||||
|  | ||||
|   | ||||
| @@ -178,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> | ||||
| @@ -560,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 | ||||
| ``` | ||||
| @@ -598,7 +604,8 @@ element_type * get() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The stored pointer. | ||||
| Returns:: | ||||
|   The stored pointer. | ||||
|  | ||||
| ### unique | ||||
| ``` | ||||
| @@ -607,7 +614,8 @@ bool unique() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `use_count() == 1`. | ||||
| Returns:: | ||||
|   `use_count() == 1`. | ||||
|  | ||||
| ### use_count | ||||
| ``` | ||||
| @@ -616,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 | ||||
| ``` | ||||
| @@ -641,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 | ||||
|  | ||||
| @@ -721,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 | ||||
| ``` | ||||
| @@ -805,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 | ||||
|  | ||||
|   | ||||
| @@ -112,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> | ||||
| @@ -185,7 +190,8 @@ NOTE: These constructors are an extension, not present in `std::weak_ptr`. | ||||
| [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 | ||||
| ``` | ||||
| @@ -214,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 | ||||
| ``` | ||||
| @@ -223,7 +230,8 @@ bool expired() const noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `use_count() == 0`. | ||||
| Returns:: | ||||
|   `use_count() == 0`. | ||||
|  | ||||
| ### empty | ||||
| ``` | ||||
| @@ -243,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 | ||||
| ``` | ||||
| @@ -252,7 +261,8 @@ void reset() noexcept; | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Equivalent to `weak_ptr().swap(*this)`. | ||||
| Effects:: | ||||
|   Equivalent to `weak_ptr().swap(*this)`. | ||||
|  | ||||
| ### swap | ||||
| ``` | ||||
| @@ -261,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; | ||||
| ``` | ||||
| @@ -272,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 | ||||
|  | ||||
| @@ -298,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; | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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,188 +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, 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 ); | ||||
| BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/lightweight_thread.hpp>") | ||||
|  | ||||
|  | ||||
| #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" void * lw_thread_routine( void * pv ) | ||||
| { | ||||
| #if defined(BOOST_NO_CXX11_SMART_PTR) | ||||
|  | ||||
|     std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) ); | ||||
|  | ||||
| #else | ||||
|  | ||||
|     std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) ); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     pt->run(); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| unsigned __stdcall lw_thread_routine( void * pv ) | ||||
| { | ||||
| #if defined(BOOST_NO_CXX11_SMART_PTR) | ||||
|  | ||||
|     std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) ); | ||||
|  | ||||
| #else | ||||
|  | ||||
|     std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) ); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     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 ) | ||||
| { | ||||
| #if defined(BOOST_NO_CXX11_SMART_PTR) | ||||
|  | ||||
|     std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) ); | ||||
|  | ||||
| #else | ||||
|  | ||||
|     std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) ); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     int r = lw_thread_create_( &th, 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 | ||||
|   | ||||
| @@ -10,6 +10,8 @@ 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 { | ||||
| @@ -17,15 +19,16 @@ namespace detail { | ||||
| 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_; | ||||
|     } | ||||
|  | ||||
| @@ -38,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_; | ||||
|     } | ||||
|  | ||||
| @@ -54,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_; | ||||
|     } | ||||
|  | ||||
| @@ -68,12 +71,12 @@ private: | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
| 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 element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::lsp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
| @@ -88,15 +91,15 @@ allocate_local_shared(const A& allocator, std::size_t count) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         count = extent<T>::value | ||||
|         count = std::extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     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, count); | ||||
| @@ -111,13 +114,13 @@ allocate_local_shared(const A& allocator) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
| 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 remove_extent<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::lsp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
| @@ -132,16 +135,16 @@ allocate_local_shared(const A& allocator, std::size_t count, | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
| 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 remove_extent<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     enum { | ||||
|         count = extent<T>::value | ||||
|         count = std::extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     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, count); | ||||
| @@ -156,7 +159,7 @@ allocate_local_shared(const A& allocator, | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
| 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) | ||||
| { | ||||
| @@ -165,7 +168,7 @@ allocate_local_shared_noinit(const A& allocator, std::size_t count) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared_noinit(const A& allocator) | ||||
| { | ||||
|   | ||||
| @@ -8,25 +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/enable_if.hpp> | ||||
| #include <boost/type_traits/extent.hpp> | ||||
| #include <boost/type_traits/is_bounded_array.hpp> | ||||
| #include <boost/type_traits/is_unbounded_array.hpp> | ||||
| #include <boost/type_traits/remove_cv.hpp> | ||||
| #include <boost/type_traits/remove_extent.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 T> | ||||
| struct sp_array_element { | ||||
|     typedef typename boost::remove_cv<typename | ||||
|         boost::remove_extent<T>::type>::type type; | ||||
|     typedef typename std::remove_cv<typename | ||||
|         std::remove_extent<T>::type>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| @@ -57,21 +52,9 @@ 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); | ||||
| } | ||||
| @@ -82,15 +65,15 @@ public: | ||||
|     typedef A type; | ||||
|  | ||||
|     template<class U> | ||||
|     sp_array_state(const U& _allocator, std::size_t _size) BOOST_SP_NOEXCEPT | ||||
|     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_; | ||||
|     } | ||||
|  | ||||
| @@ -105,14 +88,14 @@ public: | ||||
|     typedef A type; | ||||
|  | ||||
|     template<class U> | ||||
|     sp_size_array_state(const U& _allocator, std::size_t) BOOST_SP_NOEXCEPT | ||||
|     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; | ||||
|     } | ||||
|  | ||||
| @@ -123,8 +106,8 @@ private: | ||||
| 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 | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| @@ -137,7 +120,7 @@ struct sp_array_offset { | ||||
|  | ||||
| template<class U, class T> | ||||
| inline U* | ||||
| sp_array_start(T* base) BOOST_SP_NOEXCEPT | ||||
| sp_array_start(T* base) noexcept | ||||
| { | ||||
|     enum { | ||||
|         size = sp_array_offset<T, U>::value | ||||
| @@ -153,12 +136,12 @@ class sp_array_creator { | ||||
|         offset = sp_array_offset<T, element>::value | ||||
|     }; | ||||
|  | ||||
|     typedef typename boost::type_with_alignment<sp_array_alignment<T, | ||||
|     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(element) * size)) { } | ||||
|  | ||||
| @@ -171,7 +154,7 @@ public: | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     typename sp_bind_allocator<A, type>::type other_; | ||||
|     typename boost::allocator_rebind<A, type>::type other_; | ||||
|     std::size_t size_; | ||||
| }; | ||||
|  | ||||
| @@ -202,32 +185,33 @@ public: | ||||
|             boost::first_scalar(&list), count); | ||||
|     } | ||||
|  | ||||
|     T& state() BOOST_SP_NOEXCEPT { | ||||
|     T& state() noexcept { | ||||
|         return state_; | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT { | ||||
|     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() BOOST_SP_NOEXCEPT { | ||||
|     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_&) BOOST_SP_NOEXCEPT { | ||||
|     void* get_deleter(const sp_typeinfo_&) noexcept override { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void* get_local_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT { | ||||
|     void* get_local_deleter(const sp_typeinfo_&) | ||||
|         noexcept override { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void* get_untyped_deleter() BOOST_SP_NOEXCEPT { | ||||
|     void* get_untyped_deleter() noexcept override { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
| @@ -249,11 +233,11 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     T* get() const BOOST_SP_NOEXCEPT { | ||||
|     T* get() const noexcept { | ||||
|         return result_; | ||||
|     } | ||||
|  | ||||
|     void release() BOOST_SP_NOEXCEPT { | ||||
|     void release() noexcept { | ||||
|         result_ = 0; | ||||
|     } | ||||
|  | ||||
| @@ -268,11 +252,11 @@ private: | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<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 element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::sp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
| @@ -285,15 +269,15 @@ allocate_shared(const A& allocator, std::size_t count) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         count = extent<T>::value | ||||
|         count = std::extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef detail::sp_size_array_state<other, extent<T>::value> state; | ||||
|     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, count); | ||||
|     base* node = result.get(); | ||||
| @@ -305,12 +289,12 @@ allocate_shared(const A& allocator) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<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 remove_extent<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef typename allocator_rebind<A, element>::type other; | ||||
|     typedef detail::sp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
| @@ -323,16 +307,16 @@ allocate_shared(const A& allocator, std::size_t count, | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<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 remove_extent<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     enum { | ||||
|         count = extent<T>::value | ||||
|         count = std::extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef detail::sp_size_array_state<other, extent<T>::value> state; | ||||
|     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, count); | ||||
|     base* node = result.get(); | ||||
| @@ -344,14 +328,14 @@ allocate_shared(const A& allocator, | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<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) | ||||
| { | ||||
|     return boost::allocate_shared<T>(boost::noinit_adapt(allocator), count); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared_noinit(const A& allocator) | ||||
| { | ||||
|     return boost::allocate_shared<T>(boost::noinit_adapt(allocator)); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
| Copyright 2019 Glen Joseph Fernandes | ||||
| Copyright 2019-2021 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| @@ -8,41 +8,35 @@ Distributed under the Boost Software License, Version 1.0. | ||||
| #ifndef BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP | ||||
| #define BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_noexcept.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_nullptr_t.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/type_traits/enable_if.hpp> | ||||
| #include <boost/type_traits/extent.hpp> | ||||
| #include <boost/type_traits/is_array.hpp> | ||||
| #include <boost/type_traits/is_bounded_array.hpp> | ||||
| #include <boost/type_traits/is_unbounded_array.hpp> | ||||
| #include <boost/type_traits/remove_cv.hpp> | ||||
| #include <boost/type_traits/remove_extent.hpp> | ||||
| #include <boost/type_traits/type_identity.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 { | ||||
|     BOOST_STATIC_CONSTEXPR std::size_t value = 1; | ||||
|     static constexpr std::size_t value = 1; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_alloc_size<T[]> { | ||||
|     BOOST_STATIC_CONSTEXPR std::size_t value = sp_alloc_size<T>::value; | ||||
|     static constexpr std::size_t value = sp_alloc_size<T>::value; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_alloc_size<T[N]> { | ||||
|     BOOST_STATIC_CONSTEXPR std::size_t value = N * sp_alloc_size<T>::value; | ||||
|     static constexpr std::size_t value = N * sp_alloc_size<T>::value; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| @@ -57,78 +51,50 @@ struct sp_alloc_result<T[N]> { | ||||
|  | ||||
| template<class T> | ||||
| struct sp_alloc_value { | ||||
|     typedef typename boost::remove_cv<typename | ||||
|         boost::remove_extent<T>::type>::type type; | ||||
|     typedef typename std::remove_cv<typename | ||||
|         std::remove_extent<T>::type>::type type; | ||||
| }; | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_ALLOCATOR) | ||||
| template<class A, class T> | ||||
| struct sp_alloc_to { | ||||
|     typedef typename std::allocator_traits<A>::template rebind_alloc<T> type; | ||||
| }; | ||||
| #else | ||||
| template<class A, class T> | ||||
| struct sp_alloc_to { | ||||
|     typedef typename A::template rebind<T>::other type; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_ALLOCATOR) | ||||
| template<class A> | ||||
| struct sp_alloc_type { | ||||
|     typedef typename std::allocator_traits<A>::pointer type; | ||||
| }; | ||||
| #else | ||||
| template<class A> | ||||
| struct sp_alloc_type { | ||||
|     typedef typename A::pointer type; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| template<class T, class P> | ||||
| class sp_alloc_ptr { | ||||
| public: | ||||
|     typedef T element_type; | ||||
|  | ||||
|     sp_alloc_ptr() BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr() noexcept | ||||
|         : p_() { } | ||||
|  | ||||
| #if defined(BOOST_MSVC) && BOOST_MSVC == 1600 | ||||
|     sp_alloc_ptr(T* p) BOOST_SP_NOEXCEPT | ||||
|         : p_(const_cast<typename boost::remove_cv<T>::type*>(p)) { } | ||||
|     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) BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr(std::size_t, P p) noexcept | ||||
|         : p_(p) { } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_NULLPTR) | ||||
|     sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr(std::nullptr_t) noexcept | ||||
|         : p_() { } | ||||
| #endif | ||||
|  | ||||
|     T& operator*() const { | ||||
|         return *p_; | ||||
|     } | ||||
|  | ||||
|     T* operator->() const BOOST_SP_NOEXCEPT { | ||||
|     T* operator->() const noexcept { | ||||
|         return boost::to_address(p_); | ||||
|     } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) | ||||
|     explicit operator bool() const BOOST_SP_NOEXCEPT { | ||||
|     explicit operator bool() const noexcept { | ||||
|         return !!p_; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     bool operator!() const BOOST_SP_NOEXCEPT { | ||||
|     bool operator!() const noexcept { | ||||
|         return !p_; | ||||
|     } | ||||
|  | ||||
|     P ptr() const BOOST_SP_NOEXCEPT { | ||||
|     P ptr() const noexcept { | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     BOOST_STATIC_CONSTEXPR std::size_t size() BOOST_SP_NOEXCEPT { | ||||
|     static constexpr std::size_t size() noexcept { | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
| @@ -136,7 +102,7 @@ public: | ||||
|     static sp_alloc_ptr pointer_to(T& v) { | ||||
|         return sp_alloc_ptr(1, | ||||
|             std::pointer_traits<P>::pointer_to(const_cast<typename | ||||
|                 boost::remove_cv<T>::type&>(v))); | ||||
|                 std::remove_cv<T>::type&>(v))); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| @@ -149,37 +115,33 @@ class sp_alloc_ptr<T[], P> { | ||||
| public: | ||||
|     typedef T element_type; | ||||
|  | ||||
|     sp_alloc_ptr() BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr() noexcept | ||||
|         : p_() { } | ||||
|  | ||||
|     sp_alloc_ptr(std::size_t n, P p) BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr(std::size_t n, P p) noexcept | ||||
|         : p_(p) | ||||
|         , n_(n) { } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_NULLPTR) | ||||
|     sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr(std::nullptr_t) noexcept | ||||
|         : p_() { } | ||||
| #endif | ||||
|  | ||||
|     T& operator[](std::size_t i) const { | ||||
|         return p_[i]; | ||||
|     } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) | ||||
|     explicit operator bool() const BOOST_SP_NOEXCEPT { | ||||
|     explicit operator bool() const noexcept { | ||||
|         return !!p_; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     bool operator!() const BOOST_SP_NOEXCEPT { | ||||
|     bool operator!() const noexcept { | ||||
|         return !p_; | ||||
|     } | ||||
|  | ||||
|     P ptr() const BOOST_SP_NOEXCEPT { | ||||
|     P ptr() const noexcept { | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     std::size_t size() const BOOST_SP_NOEXCEPT { | ||||
|     std::size_t size() const noexcept { | ||||
|         return n_; | ||||
|     } | ||||
|  | ||||
| @@ -187,7 +149,7 @@ public: | ||||
|     static sp_alloc_ptr pointer_to(T& v) { | ||||
|         return sp_alloc_ptr(n_, | ||||
|             std::pointer_traits<P>::pointer_to(const_cast<typename | ||||
|                 boost::remove_cv<T>::type&>(v))); | ||||
|                 std::remove_cv<T>::type&>(v))); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| @@ -201,36 +163,32 @@ class sp_alloc_ptr<T[N], P> { | ||||
| public: | ||||
|     typedef T element_type; | ||||
|  | ||||
|     sp_alloc_ptr() BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr() noexcept | ||||
|         : p_() { } | ||||
|  | ||||
|     sp_alloc_ptr(std::size_t, P p) BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr(std::size_t, P p) noexcept | ||||
|         : p_(p) { } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_NULLPTR) | ||||
|     sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT | ||||
|     sp_alloc_ptr(std::nullptr_t) noexcept | ||||
|         : p_() { } | ||||
| #endif | ||||
|  | ||||
|     T& operator[](std::size_t i) const { | ||||
|         return p_[i]; | ||||
|     } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) | ||||
|     explicit operator bool() const BOOST_SP_NOEXCEPT { | ||||
|     explicit operator bool() const noexcept { | ||||
|         return !!p_; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     bool operator!() const BOOST_SP_NOEXCEPT { | ||||
|     bool operator!() const noexcept { | ||||
|         return !p_; | ||||
|     } | ||||
|  | ||||
|     P ptr() const BOOST_SP_NOEXCEPT { | ||||
|     P ptr() const noexcept { | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     BOOST_STATIC_CONSTEXPR std::size_t size() BOOST_SP_NOEXCEPT { | ||||
|     static constexpr std::size_t size() noexcept { | ||||
|         return N; | ||||
|     } | ||||
|  | ||||
| @@ -238,7 +196,7 @@ public: | ||||
|     static sp_alloc_ptr pointer_to(T& v) { | ||||
|         return sp_alloc_ptr(N, | ||||
|             std::pointer_traits<P>::pointer_to(const_cast<typename | ||||
|                 boost::remove_cv<T>::type&>(v))); | ||||
|                 std::remove_cv<T>::type&>(v))); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| @@ -260,19 +218,18 @@ operator!=(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs) | ||||
|     return !(lhs == rhs); | ||||
| } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_NULLPTR) | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator==(const sp_alloc_ptr<T, P>& lhs, | ||||
|     detail::sp_nullptr_t) BOOST_SP_NOEXCEPT | ||||
|     std::nullptr_t) noexcept | ||||
| { | ||||
|     return !lhs.ptr(); | ||||
| } | ||||
|  | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator==(detail::sp_nullptr_t, | ||||
|     const sp_alloc_ptr<T, P>& rhs) BOOST_SP_NOEXCEPT | ||||
| operator==(std::nullptr_t, | ||||
|     const sp_alloc_ptr<T, P>& rhs) noexcept | ||||
| { | ||||
|     return !rhs.ptr(); | ||||
| } | ||||
| @@ -280,32 +237,31 @@ operator==(detail::sp_nullptr_t, | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator!=(const sp_alloc_ptr<T, P>& lhs, | ||||
|     detail::sp_nullptr_t) BOOST_SP_NOEXCEPT | ||||
|     std::nullptr_t) noexcept | ||||
| { | ||||
|     return !!lhs.ptr(); | ||||
| } | ||||
|  | ||||
| template<class T, class P> | ||||
| inline bool | ||||
| operator!=(detail::sp_nullptr_t, | ||||
|     const sp_alloc_ptr<T, P>& rhs) BOOST_SP_NOEXCEPT | ||||
| operator!=(std::nullptr_t, | ||||
|     const sp_alloc_ptr<T, P>& rhs) noexcept | ||||
| { | ||||
|     return !!rhs.ptr(); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| template<class A> | ||||
| inline void | ||||
| sp_alloc_clear(A& a, typename sp_alloc_type<A>::type p, std::size_t, | ||||
|     boost::false_type) | ||||
| 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 sp_alloc_type<A>::type p, std::size_t n, | ||||
|     boost::true_type) | ||||
| 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) { | ||||
| @@ -320,36 +276,34 @@ sp_alloc_clear(A& a, typename sp_alloc_type<A>::type p, std::size_t n, | ||||
|  | ||||
| template<class T, class A> | ||||
| class alloc_deleter | ||||
|     : empty_value<typename detail::sp_alloc_to<A, | ||||
|     : empty_value<typename allocator_rebind<A, | ||||
|         typename detail::sp_alloc_value<T>::type>::type> { | ||||
|     typedef typename detail::sp_alloc_to<A, | ||||
|     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 detail::sp_alloc_type<allocator>::type> pointer; | ||||
|         typename allocator_pointer<allocator>::type> pointer; | ||||
|  | ||||
|     explicit alloc_deleter(const allocator& a) BOOST_SP_NOEXCEPT | ||||
|     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(), is_array<T>()); | ||||
|         detail::sp_alloc_clear(base::get(), p.ptr(), p.size(), std::is_array<T>()); | ||||
|         base::get().deallocate(p.ptr(), p.size()); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) | ||||
| template<class T, class A> | ||||
| using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A> >; | ||||
| #endif | ||||
|  | ||||
| namespace detail { | ||||
|  | ||||
| template<class T, class A> | ||||
| class sp_alloc_make { | ||||
| public: | ||||
|     typedef typename sp_alloc_to<A, | ||||
|     typedef typename boost::allocator_rebind<A, | ||||
|         typename sp_alloc_value<T>::type>::type allocator; | ||||
|  | ||||
| private: | ||||
| @@ -369,22 +323,22 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     typename allocator::value_type* get() const BOOST_SP_NOEXCEPT { | ||||
|     typename allocator::value_type* get() const noexcept { | ||||
|         return boost::to_address(p_); | ||||
|     } | ||||
|  | ||||
|     allocator& state() BOOST_SP_NOEXCEPT { | ||||
|     allocator& state() noexcept { | ||||
|         return a_; | ||||
|     } | ||||
|  | ||||
|     type release() BOOST_SP_NOEXCEPT { | ||||
|     type release() noexcept { | ||||
|         pointer p = p_; | ||||
|         p_ = pointer(); | ||||
|         return type(typename deleter::pointer(n_, p), deleter(a_)); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     typedef typename sp_alloc_type<allocator>::type pointer; | ||||
|     typedef typename boost::allocator_pointer<allocator>::type pointer; | ||||
|  | ||||
|     allocator a_; | ||||
|     std::size_t n_; | ||||
| @@ -394,7 +348,7 @@ private: | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<!is_array<T>::value, | ||||
| inline typename std::enable_if<!std::is_array<T>::value, | ||||
|     std::unique_ptr<T, alloc_deleter<T, A> > >::type | ||||
| allocate_unique(const A& alloc) | ||||
| { | ||||
| @@ -403,9 +357,8 @@ allocate_unique(const A& alloc) | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | ||||
| template<class T, class A, class... Args> | ||||
| inline typename enable_if_<!is_array<T>::value, | ||||
| 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) | ||||
| { | ||||
| @@ -413,12 +366,11 @@ allocate_unique(const A& alloc, Args&&... args) | ||||
|     boost::alloc_construct(c.state(), c.get(), std::forward<Args>(args)...); | ||||
|     return c.release(); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<!is_array<T>::value, | ||||
| 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 type_identity<T>::type&& value) | ||||
| 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)); | ||||
| @@ -426,7 +378,7 @@ allocate_unique(const A& alloc, typename type_identity<T>::type&& value) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<!is_array<T>::value, | ||||
| 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) | ||||
| { | ||||
| @@ -434,7 +386,7 @@ allocate_unique_noinit(const A& alloc) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
| 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) | ||||
| { | ||||
| @@ -445,19 +397,19 @@ allocate_unique(const A& alloc, std::size_t size) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
| 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, extent<T>::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); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
| 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) | ||||
| { | ||||
| @@ -465,7 +417,7 @@ allocate_unique_noinit(const A& alloc, std::size_t size) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
| 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) | ||||
| @@ -474,32 +426,41 @@ allocate_unique_noinit(const A& alloc) | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
| 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 remove_extent<T>::type& value) | ||||
|     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 remove_extent<T>::type>::value); | ||||
|         detail::sp_alloc_size<typename std::remove_extent<T>::type>::value); | ||||
|     return c.release(); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
| 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 remove_extent<T>::type& value) | ||||
|     const typename std::remove_extent<T>::type& value) | ||||
| { | ||||
|     detail::sp_alloc_make<T, A> c(alloc, extent<T>::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 remove_extent<T>::type>::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,39 +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 | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT | ||||
|     atomic_shared_ptr( shared_ptr<T> p ) noexcept | ||||
|         : p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT | ||||
|     { | ||||
|     } | ||||
|  | ||||
| #else | ||||
|  | ||||
|     atomic_shared_ptr() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; | ||||
|         std::memcpy( &l_, &init, sizeof( init ) ); | ||||
|     } | ||||
|  | ||||
|     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 ) ); | ||||
|     } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     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 ); | ||||
| @@ -97,140 +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() const BOOST_SP_NOEXCEPT | ||||
|     shared_ptr<T> load() const noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT | ||||
|     template<class M> shared_ptr<T> load( M ) const noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     operator shared_ptr<T>() const BOOST_SP_NOEXCEPT | ||||
|     operator shared_ptr<T>() const noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT | ||||
|     void store( shared_ptr<T> r ) noexcept | ||||
|     { | ||||
|         boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|         p_.swap( r ); | ||||
|     } | ||||
|  | ||||
|     template<class M> void store( shared_ptr<T> r, M ) 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 ) BOOST_SP_NOEXCEPT | ||||
|     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 ); | ||||
|  | ||||
| #else | ||||
|  | ||||
|         return r; | ||||
|  | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT | ||||
|     template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) noexcept | ||||
|     { | ||||
|         { | ||||
|             boost::detail::spinlock::scoped_lock lock( l_ ); | ||||
|             p_.swap( r ); | ||||
|         } | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|  | ||||
|         return std::move( r ); | ||||
|  | ||||
| #else | ||||
|  | ||||
|         return r; | ||||
|  | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) 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 ); | ||||
|     } | ||||
|  | ||||
|     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) 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_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT | ||||
|     bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, w ); | ||||
|     } | ||||
|  | ||||
|     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) 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 ); | ||||
|     } | ||||
|  | ||||
|     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT | ||||
|     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_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT | ||||
|     bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, w ); | ||||
|     } | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|  | ||||
|     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT | ||||
|     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 ) ); | ||||
|     } | ||||
|  | ||||
|     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) 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_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT | ||||
|     bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, std::move( w ) ); | ||||
|     } | ||||
|  | ||||
|     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) 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 ) ); | ||||
|     } | ||||
|  | ||||
|     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT | ||||
|     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 ) BOOST_SP_NOEXCEPT | ||||
|     bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) noexcept | ||||
|     { | ||||
|         return compare_exchange( v, std::move( w ) ); | ||||
|     } | ||||
|  | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| } // 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 BOOST_NOEXCEPT_OR_NOTHROW | ||||
|     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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
							
								
								
									
										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 | ||||
| @@ -42,23 +42,23 @@ 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 ) | ||||
| @@ -73,7 +73,7 @@ public: | ||||
|         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 ); | ||||
|  | ||||
| @@ -83,7 +83,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long local_use_count() const BOOST_SP_NOEXCEPT | ||||
|     long local_use_count() const noexcept | ||||
|     { | ||||
|         return local_use_count_; | ||||
|     } | ||||
| @@ -101,24 +101,20 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     explicit local_counted_impl( shared_count const& pn ) BOOST_SP_NOEXCEPT: 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 ) BOOST_SP_NOEXCEPT: 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_; | ||||
|     } | ||||
| @@ -130,12 +126,12 @@ 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() BOOST_SP_NOEXCEPT | ||||
|     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 ) BOOST_SP_NOEXCEPT | ||||
| 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*/ ) BOOST_SP_NOEXCEPT | ||||
| inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) noexcept | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -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,32 +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/smart_ptr/detail/sp_noexcept.hpp> | ||||
| #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> | ||||
| // 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/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" | ||||
| @@ -62,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 | ||||
| @@ -103,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 | ||||
| @@ -111,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() BOOST_SP_NOEXCEPT: pi_(0) | ||||
| #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 ) BOOST_SP_NOEXCEPT: pi_( pi ) | ||||
| #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 | ||||
|  | ||||
| @@ -163,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 | ||||
| @@ -200,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 | ||||
|  | ||||
| @@ -232,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 | ||||
| @@ -289,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 | ||||
| @@ -346,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 | ||||
|  | ||||
| @@ -372,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 | ||||
| @@ -397,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; | ||||
|  | ||||
| @@ -422,38 +347,25 @@ public: | ||||
|         r.release(); | ||||
|     } | ||||
|  | ||||
|     ~shared_count() /*BOOST_SP_NOEXCEPT*/ | ||||
|     ~shared_count() /*noexcept*/ | ||||
|     { | ||||
|         if( pi_ != 0 ) pi_->release(); | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         id_ = 0; | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     shared_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #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) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #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 ) BOOST_SP_NOEXCEPT; // 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) BOOST_SP_NOEXCEPT | ||||
|     shared_count & operator= (shared_count const & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -467,52 +379,61 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     void swap(shared_count & r) BOOST_SP_NOEXCEPT | ||||
|     void swap(shared_count & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|         r.pi_ = pi_; | ||||
|         pi_ = tmp; | ||||
|     } | ||||
|  | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     long use_count() const noexcept | ||||
|     { | ||||
|         return pi_ != 0? pi_->use_count(): 0; | ||||
|     } | ||||
|  | ||||
|     bool unique() const BOOST_SP_NOEXCEPT | ||||
|     bool unique() const noexcept | ||||
|     { | ||||
|         return use_count() == 1; | ||||
|     } | ||||
|  | ||||
|     bool empty() const BOOST_SP_NOEXCEPT | ||||
|     bool empty() const noexcept | ||||
|     { | ||||
|         return pi_ == 0; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator==(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT | ||||
|     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) BOOST_SP_NOEXCEPT | ||||
|     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 BOOST_SP_NOEXCEPT | ||||
|     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 BOOST_SP_NOEXCEPT | ||||
|     void * get_local_deleter( sp_typeinfo_ const & ti ) const noexcept | ||||
|     { | ||||
|         return pi_? pi_->get_local_deleter( ti ): 0; | ||||
|     } | ||||
|  | ||||
|     void * get_untyped_deleter() const BOOST_SP_NOEXCEPT | ||||
|     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_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -522,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() BOOST_SP_NOEXCEPT: pi_(0) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(weak_count_id) | ||||
| #endif | ||||
|     constexpr weak_count() noexcept: pi_(0) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     weak_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #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) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #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) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #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() /*BOOST_SP_NOEXCEPT*/ | ||||
|     ~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) BOOST_SP_NOEXCEPT | ||||
|     weak_count & operator= (shared_count const & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -589,7 +487,7 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     weak_count & operator= (weak_count const & r) BOOST_SP_NOEXCEPT | ||||
|     weak_count & operator= (weak_count const & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -603,38 +501,50 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     void swap(weak_count & r) BOOST_SP_NOEXCEPT | ||||
|     void swap(weak_count & r) noexcept | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|         r.pi_ = pi_; | ||||
|         pi_ = tmp; | ||||
|     } | ||||
|  | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     long use_count() const noexcept | ||||
|     { | ||||
|         return pi_ != 0? pi_->use_count(): 0; | ||||
|     } | ||||
|  | ||||
|     bool empty() const BOOST_SP_NOEXCEPT | ||||
|     bool empty() const noexcept | ||||
|     { | ||||
|         return pi_ == 0; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator==(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT | ||||
|     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) BOOST_SP_NOEXCEPT | ||||
|     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() ) | ||||
|     { | ||||
| @@ -642,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 ) BOOST_SP_NOEXCEPT: 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() ) | ||||
|     { | ||||
| @@ -653,6 +560,16 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_ | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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 | ||||
| @@ -661,8 +578,4 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_ | ||||
| #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 | ||||
|   | ||||
| @@ -16,9 +16,19 @@ | ||||
| // | ||||
|  | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -25,6 +25,13 @@ | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -1,152 +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/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_noexcept.hpp> | ||||
| #include <boost/config.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 ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     __c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED ); | ||||
| } | ||||
|  | ||||
| inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL ); | ||||
| } | ||||
|  | ||||
| inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     // 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 BOOST_SYMBOL_VISIBLE 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() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         __c11_atomic_init( &use_count_, 1 ); | ||||
|         __c11_atomic_init( &weak_count_, 1 ); | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // dispose() is called when use_count_ drops to zero, to release | ||||
|     // the resources managed by *this. | ||||
|  | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow | ||||
|  | ||||
|     // destroy() is called when weak_count_ drops to zero. | ||||
|  | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT // nothrow | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0; | ||||
|  | ||||
|     void add_ref_copy() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         atomic_increment( &use_count_ ); | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success | ||||
|     { | ||||
|         return atomic_conditional_increment( &use_count_ ) != 0; | ||||
|     } | ||||
|  | ||||
|     void release() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         if( atomic_decrement( &use_count_ ) == 1 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 1 ) | ||||
|         { | ||||
|             destroy(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         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 | ||||
| @@ -25,8 +25,16 @@ | ||||
| // | ||||
|  | ||||
| #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 | ||||
| { | ||||
|  | ||||
| @@ -54,7 +62,11 @@ inline long atomic_decrement( register long * pw ) | ||||
|  | ||||
|     asm | ||||
|     { | ||||
| #if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__) | ||||
|     msync | ||||
| #else | ||||
|     sync | ||||
| #endif | ||||
|  | ||||
| loop: | ||||
|  | ||||
|   | ||||
| @@ -1,161 +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/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.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 BOOST_SYMBOL_VISIBLE 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 | ||||
| @@ -17,8 +17,18 @@ | ||||
| // | ||||
|  | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -21,8 +21,18 @@ | ||||
| // | ||||
|  | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -25,8 +25,18 @@ | ||||
| // | ||||
|  | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -20,9 +20,19 @@ | ||||
| //  Thanks to Michael van der Westhuizen | ||||
|  | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -25,8 +25,18 @@ | ||||
| // | ||||
|  | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -19,10 +19,16 @@ | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_noexcept.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 | ||||
| { | ||||
|  | ||||
| @@ -41,43 +47,43 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 ) | ||||
|     sp_counted_base() noexcept: use_count_( 1 ), weak_count_( 1 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/ | ||||
|     virtual ~sp_counted_base() /*noexcept*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // dispose() is called when use_count_ drops to zero, to release | ||||
|     // the resources managed by *this. | ||||
|  | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow | ||||
|     virtual void dispose() noexcept = 0; // nothrow | ||||
|  | ||||
|     // destroy() is called when weak_count_ drops to zero. | ||||
|  | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT // nothrow | ||||
|     virtual void destroy() noexcept // nothrow | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 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() BOOST_SP_NOEXCEPT | ||||
|     void add_ref_copy() noexcept | ||||
|     { | ||||
|         ++use_count_; | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success | ||||
|     bool add_ref_lock() noexcept // true on success | ||||
|     { | ||||
|         if( use_count_ == 0 ) return false; | ||||
|         ++use_count_; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     void release() BOOST_SP_NOEXCEPT | ||||
|     void release() noexcept | ||||
|     { | ||||
|         if( --use_count_ == 0 ) | ||||
|         { | ||||
| @@ -86,12 +92,12 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() BOOST_SP_NOEXCEPT | ||||
|     void weak_add_ref() noexcept | ||||
|     { | ||||
|         ++weak_count_; | ||||
|     } | ||||
|  | ||||
|     void weak_release() BOOST_SP_NOEXCEPT | ||||
|     void weak_release() noexcept | ||||
|     { | ||||
|         if( --weak_count_ == 0 ) | ||||
|         { | ||||
| @@ -99,7 +105,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     long use_count() const noexcept | ||||
|     { | ||||
|         return use_count_; | ||||
|     } | ||||
|   | ||||
| @@ -24,6 +24,13 @@ | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| @@ -20,9 +20,19 @@ | ||||
| //  Thanks to Michael van der Westhuizen | ||||
|  | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -1,116 +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/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <atomic.h> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class BOOST_SYMBOL_VISIBLE 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 | ||||
| @@ -22,6 +22,13 @@ | ||||
| #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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -16,28 +16,34 @@ | ||||
| //  http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_noexcept.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 ) BOOST_SP_NOEXCEPT | ||||
| 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 ) BOOST_SP_NOEXCEPT | ||||
| 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 ) BOOST_SP_NOEXCEPT | ||||
| inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) noexcept | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // if( r != 0 ) ++*pw; | ||||
| @@ -71,41 +77,41 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 ) | ||||
|     sp_counted_base() noexcept: use_count_( 1 ), weak_count_( 1 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/ | ||||
|     virtual ~sp_counted_base() /*noexcept*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // dispose() is called when use_count_ drops to zero, to release | ||||
|     // the resources managed by *this. | ||||
|  | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual void dispose() noexcept = 0; | ||||
|  | ||||
|     // destroy() is called when weak_count_ drops to zero. | ||||
|  | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT | ||||
|     virtual void destroy() noexcept | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0; | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 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() BOOST_SP_NOEXCEPT | ||||
|     void add_ref_copy() noexcept | ||||
|     { | ||||
|         atomic_increment( &use_count_ ); | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success | ||||
|     bool add_ref_lock() noexcept // true on success | ||||
|     { | ||||
|         return atomic_conditional_increment( &use_count_ ) != 0; | ||||
|     } | ||||
|  | ||||
|     void release() BOOST_SP_NOEXCEPT | ||||
|     void release() noexcept | ||||
|     { | ||||
|         if( atomic_decrement( &use_count_ ) == 1 ) | ||||
|         { | ||||
| @@ -114,12 +120,12 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() BOOST_SP_NOEXCEPT | ||||
|     void weak_add_ref() noexcept | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() BOOST_SP_NOEXCEPT | ||||
|     void weak_release() noexcept | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 1 ) | ||||
|         { | ||||
| @@ -127,7 +133,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     long use_count() const noexcept | ||||
|     { | ||||
|         return use_count_.load( std::memory_order_acquire ); | ||||
|     } | ||||
|   | ||||
| @@ -23,6 +23,13 @@ | ||||
| # 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 | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -22,8 +22,18 @@ | ||||
| // | ||||
|  | ||||
| #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); | ||||
| extern "builtin" int __fetch_and_add(volatile int* addr, int val); | ||||
|   | ||||
| @@ -29,6 +29,13 @@ | ||||
| #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 | ||||
| { | ||||
|  | ||||
| @@ -83,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,37 +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/smart_ptr/detail/sp_noexcept.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 | ||||
| { | ||||
|  | ||||
| @@ -56,12 +37,12 @@ namespace detail | ||||
|  | ||||
| template<class D> class local_sp_deleter; | ||||
|  | ||||
| template<class D> D * get_local_deleter( D * /*p*/ ) BOOST_SP_NOEXCEPT | ||||
| template<class D> D * get_local_deleter( D * /*p*/ ) noexcept | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT; | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept; | ||||
|  | ||||
| // | ||||
|  | ||||
| @@ -80,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() BOOST_SP_NOEXCEPT | ||||
|     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 & ) BOOST_SP_NOEXCEPT | ||||
|     void * get_deleter( sp_typeinfo_ const & ) noexcept override | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT | ||||
|     void * get_local_deleter( sp_typeinfo_ const & ) noexcept override | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT | ||||
|     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 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 & ); | ||||
| @@ -160,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 ) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| @@ -168,53 +108,25 @@ public: | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT | ||||
|     void dispose() noexcept override | ||||
|     { | ||||
|         del( ptr ); | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT | ||||
|     void * get_deleter( sp_typeinfo_ const & ti ) noexcept override | ||||
|     { | ||||
|         return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT | ||||
|     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; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT | ||||
|     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 BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base | ||||
| @@ -222,7 +134,7 @@ template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p | ||||
| 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 & ); | ||||
| @@ -234,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 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| @@ -242,23 +154,15 @@ public: | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT | ||||
|     void dispose() noexcept override | ||||
|     { | ||||
|         d_( p_ ); | ||||
|     } | ||||
|  | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT | ||||
|     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(); | ||||
| @@ -266,26 +170,22 @@ public: | ||||
|         a2.deallocate( this, 1 ); | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT | ||||
|     void * get_deleter( sp_typeinfo_ const & ti ) noexcept override | ||||
|     { | ||||
|         return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT | ||||
|     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; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT | ||||
|     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 | ||||
| @@ -15,25 +15,16 @@ | ||||
| //  See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| // BOOST_SP_NOEXCEPT | ||||
| // BOOST_SP_NOEXCEPT (obsolete, only retained for compatibility) | ||||
|  | ||||
| #if defined( BOOST_MSVC ) && BOOST_MSVC >= 1700 && BOOST_MSVC < 1900 | ||||
| #define BOOST_SP_NOEXCEPT noexcept | ||||
|  | ||||
| #  define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW | ||||
|  | ||||
| #else | ||||
|  | ||||
| #  define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // BOOST_SP_NOEXCEPT_WITH_ASSERT | ||||
| // BOOST_SP_NOEXCEPT_WITH_ASSERT (noexcept, unless a user assertion handler is present) | ||||
|  | ||||
| #if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ) | ||||
|  | ||||
| #  define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_NOEXCEPT | ||||
| #  define BOOST_SP_NOEXCEPT_WITH_ASSERT noexcept | ||||
|  | ||||
| #elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) ) | ||||
|  | ||||
| @@ -41,7 +32,7 @@ | ||||
|  | ||||
| #else | ||||
|  | ||||
| #  define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_NOEXCEPT | ||||
| #  define BOOST_SP_NOEXCEPT_WITH_ASSERT noexcept | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -1,45 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| //  detail/sp_nullptr_t.hpp | ||||
| // | ||||
| //  Copyright 2013 Peter Dimov | ||||
| // | ||||
| //  Distributed under the Boost Software License, Version 1.0. | ||||
| //  See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <cstddef> | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_NULLPTR ) | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) ) | ||||
|  | ||||
|     typedef decltype(nullptr) sp_nullptr_t; | ||||
|  | ||||
| #else | ||||
|  | ||||
|     typedef std::nullptr_t sp_nullptr_t; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // !defined( BOOST_NO_CXX11_NULLPTR ) | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED | ||||
							
								
								
									
										32
									
								
								include/boost/smart_ptr/detail/sp_obsolete.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								include/boost/smart_ptr/detail/sp_obsolete.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
|  | ||||
| // boost/smart_ptr/detail/sp_obsolete.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_OBSOLETE macro that emits a deprecation | ||||
| // message. | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
|  | ||||
| #if !defined( BOOST_SP_NO_OBSOLETE_MESSAGE ) | ||||
|  | ||||
| #define BOOST_SP_OBSOLETE() BOOST_PRAGMA_MESSAGE("This platform-specific implementation is presumed obsolete and is slated for removal. If you want it retained, please open an issue in https://github.com/boostorg/smart_ptr.") | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define BOOST_SP_OBSOLETE() | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED | ||||
							
								
								
									
										23
									
								
								include/boost/smart_ptr/detail/sp_thread_pause.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								include/boost/smart_ptr/detail/sp_thread_pause.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED | ||||
|  | ||||
| // Copyright 2023 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/core/yield_primitives.hpp> | ||||
| #include <boost/config/header_deprecated.hpp> | ||||
|  | ||||
| BOOST_HEADER_DEPRECATED( "<boost/core/yield_primitives.hpp>" ) | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| using boost::core::sp_thread_pause; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED | ||||
							
								
								
									
										23
									
								
								include/boost/smart_ptr/detail/sp_thread_sleep.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								include/boost/smart_ptr/detail/sp_thread_sleep.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED | ||||
|  | ||||
| // Copyright 2023 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/core/yield_primitives.hpp> | ||||
| #include <boost/config/header_deprecated.hpp> | ||||
|  | ||||
| BOOST_HEADER_DEPRECATED( "<boost/core/yield_primitives.hpp>" ) | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| using boost::core::sp_thread_sleep; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED | ||||
							
								
								
									
										23
									
								
								include/boost/smart_ptr/detail/sp_thread_yield.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								include/boost/smart_ptr/detail/sp_thread_yield.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED | ||||
|  | ||||
| // Copyright 2023 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <boost/core/yield_primitives.hpp> | ||||
| #include <boost/config/header_deprecated.hpp> | ||||
|  | ||||
| BOOST_HEADER_DEPRECATED( "<boost/core/yield_primitives.hpp>" ) | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| using boost::core::sp_thread_yield; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED | ||||
							
								
								
									
										55
									
								
								include/boost/smart_ptr/detail/sp_type_traits.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								include/boost/smart_ptr/detail/sp_type_traits.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_TYPE_TRAITS_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_TYPE_TRAITS_HPP_INCLUDED | ||||
|  | ||||
| // Copyright 2024 Peter Dimov | ||||
| // Distributed under the Boost Software License, Version 1.0. | ||||
| // https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #include <type_traits> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| // std::is_bounded_array (C++20) | ||||
|  | ||||
| template<class T> struct sp_is_bounded_array: std::false_type | ||||
| { | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> struct sp_is_bounded_array< T[N] >: std::true_type | ||||
| { | ||||
| }; | ||||
|  | ||||
| // std::is_unbounded_array (C++20) | ||||
|  | ||||
| template<class T> struct sp_is_unbounded_array: std::false_type | ||||
| { | ||||
| }; | ||||
|  | ||||
| template<class T> struct sp_is_unbounded_array< T[] >: std::true_type | ||||
| { | ||||
| }; | ||||
|  | ||||
| // std::type_identity (C++20) | ||||
|  | ||||
| template<class T> struct sp_type_identity | ||||
| { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| // boost::type_with_alignment | ||||
|  | ||||
| template<std::size_t A> struct sp_type_with_alignment | ||||
| { | ||||
|     struct alignas(A) type | ||||
|     { | ||||
|         unsigned char padding[ A ]; | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_TYPE_TRAITS_HPP_INCLUDED | ||||
| @@ -28,28 +28,27 @@ | ||||
| //  #define BOOST_DETAIL_SPINLOCK_INIT <unspecified> | ||||
| // | ||||
|  | ||||
| #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_SP_USE_STD_ATOMIC ) | ||||
| # if !defined( __clang__ ) | ||||
| #   include <boost/smart_ptr/detail/spinlock_std_atomic.hpp> | ||||
| # else | ||||
| //  Clang (at least up to 3.4) can't compile spinlock_pool when | ||||
| //  using std::atomic, so substitute the __sync implementation instead. | ||||
| #   include <boost/smart_ptr/detail/spinlock_sync.hpp> | ||||
| # endif | ||||
| #  include <boost/smart_ptr/detail/spinlock_std_atomic.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_USE_PTHREADS ) | ||||
| #  include <boost/smart_ptr/detail/spinlock_pt.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_HAS_GCC_INTRINSICS ) | ||||
| #  include <boost/smart_ptr/detail/spinlock_gcc_atomic.hpp> | ||||
|  | ||||
| #elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) | ||||
| #  include <boost/smart_ptr/detail/spinlock_std_atomic.hpp> | ||||
|  | ||||
| #elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ ) | ||||
| #  include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_HAS_SYNC ) | ||||
| #elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) | ||||
| #  include <boost/smart_ptr/detail/spinlock_sync.hpp> | ||||
|  | ||||
| #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) | ||||
|   | ||||
| @@ -11,6 +11,13 @@ | ||||
|  | ||||
| #include <boost/smart_ptr/detail/yield_k.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/ARM spinlock") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__) | ||||
|  | ||||
| # define BOOST_SP_ARM_BARRIER "dmb" | ||||
|   | ||||
							
								
								
									
										94
									
								
								include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // Copyright 2008, 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/yield_k.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using __atomic spinlock") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class spinlock | ||||
| { | ||||
| public: | ||||
|  | ||||
|     // `bool` alignment is required for Apple PPC32 | ||||
|     // https://github.com/boostorg/smart_ptr/issues/105 | ||||
|     // https://github.com/PurpleI2P/i2pd/issues/1726 | ||||
|     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107590 | ||||
|  | ||||
|     union | ||||
|     { | ||||
|         unsigned char v_; | ||||
|         bool align_; | ||||
|     }; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     bool try_lock() | ||||
|     { | ||||
|         return __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 0; | ||||
|     } | ||||
|  | ||||
|     void lock() | ||||
|     { | ||||
|         for( unsigned k = 0; !try_lock(); ++k ) | ||||
|         { | ||||
|             boost::detail::yield( k ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void unlock() | ||||
|     { | ||||
|         __atomic_clear( &v_, __ATOMIC_RELEASE ); | ||||
|     } | ||||
|  | ||||
| public: | ||||
|  | ||||
|     class scoped_lock | ||||
|     { | ||||
|     private: | ||||
|  | ||||
|         spinlock & sp_; | ||||
|  | ||||
|         scoped_lock( scoped_lock const & ); | ||||
|         scoped_lock & operator=( scoped_lock const & ); | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         explicit scoped_lock( spinlock & sp ): sp_( sp ) | ||||
|         { | ||||
|             sp.lock(); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         { | ||||
|             sp_.unlock(); | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #define BOOST_DETAIL_SPINLOCK_INIT {{0}} | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED | ||||
| @@ -17,6 +17,13 @@ | ||||
|  | ||||
| #include <boost/assert.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using single-threaded spinlock emulation") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -17,6 +17,13 @@ | ||||
|  | ||||
| #include <pthread.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using pthread_mutex spinlock emulation") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -16,9 +16,15 @@ | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/yield_k.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <atomic> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using std::atomic spinlock") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| @@ -33,12 +39,12 @@ public: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     bool try_lock() BOOST_NOEXCEPT | ||||
|     bool try_lock() noexcept | ||||
|     { | ||||
|         return !v_.test_and_set( std::memory_order_acquire ); | ||||
|     } | ||||
|  | ||||
|     void lock() BOOST_NOEXCEPT | ||||
|     void lock() noexcept | ||||
|     { | ||||
|         for( unsigned k = 0; !try_lock(); ++k ) | ||||
|         { | ||||
| @@ -46,7 +52,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void unlock() BOOST_NOEXCEPT | ||||
|     void unlock() noexcept | ||||
|     { | ||||
|         v_ .clear( std::memory_order_release ); | ||||
|     } | ||||
| @@ -64,12 +70,12 @@ public: | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         explicit scoped_lock( spinlock & sp ) BOOST_NOEXCEPT: sp_( sp ) | ||||
|         explicit scoped_lock( spinlock & sp ) noexcept: sp_( sp ) | ||||
|         { | ||||
|             sp.lock(); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() /*BOOST_NOEXCEPT*/ | ||||
|         ~scoped_lock() /*noexcept*/ | ||||
|         { | ||||
|             sp_.unlock(); | ||||
|         } | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user