forked from boostorg/smart_ptr
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			feature/mo
			...
			boost-1.22
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a59fb9bccd | 
							
								
								
									
										324
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										324
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,324 +0,0 @@
 | 
			
		||||
# Copyright 2016-2019 Peter Dimov
 | 
			
		||||
# Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
language: cpp
 | 
			
		||||
 | 
			
		||||
sudo: false
 | 
			
		||||
 | 
			
		||||
branches:
 | 
			
		||||
  only:
 | 
			
		||||
    - master
 | 
			
		||||
    - develop
 | 
			
		||||
    - /feature\/.*/
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  matrix:
 | 
			
		||||
    - BOGUS_JOB=true
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
 | 
			
		||||
  exclude:
 | 
			
		||||
    - env: BOGUS_JOB=true
 | 
			
		||||
 | 
			
		||||
  include:
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-4.4
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-4.4
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-4.6
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-4.6
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-4.7
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-4.7
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-4.8
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-4.8
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-4.9
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-4.9
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-5
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-5
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-6
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-6
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-7
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-7
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++-8
 | 
			
		||||
      env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - g++-8
 | 
			
		||||
          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
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: /usr/bin/clang++
 | 
			
		||||
      env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-3.3
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: /usr/bin/clang++
 | 
			
		||||
      env: TOOLSET=clang COMPILER=/usr/bin/clang++ 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,14,1z
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-3.5
 | 
			
		||||
            - libstdc++-4.9-dev
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
            - llvm-toolchain-precise-3.5
 | 
			
		||||
 | 
			
		||||
    - 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
 | 
			
		||||
            - llvm-toolchain-precise-3.6
 | 
			
		||||
 | 
			
		||||
    - 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
 | 
			
		||||
            - llvm-toolchain-precise-3.7
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-3.8
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-3.8
 | 
			
		||||
            - libstdc++-4.9-dev
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
            - llvm-toolchain-precise-3.8
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-3.9
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-3.9
 | 
			
		||||
            - libstdc++-4.9-dev
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
            - llvm-toolchain-precise-3.9
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-4.0
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-4.0
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
            - llvm-toolchain-trusty-4.0
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-5.0
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-5.0
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
            - llvm-toolchain-trusty-5.0
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-6.0
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-6.0
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
            - llvm-toolchain-trusty-6.0
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-7
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-7
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
            - llvm-toolchain-trusty-7
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-7
 | 
			
		||||
      env: UBSAN=1 TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - clang-7
 | 
			
		||||
            - libstdc++-5-dev
 | 
			
		||||
          sources:
 | 
			
		||||
            - ubuntu-toolchain-r-test
 | 
			
		||||
            - llvm-toolchain-trusty-7
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-libc++
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - libc++-dev
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: clang++-libc++
 | 
			
		||||
      env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          packages:
 | 
			
		||||
            - libc++-dev
 | 
			
		||||
 | 
			
		||||
    - os: osx
 | 
			
		||||
      compiler: clang++
 | 
			
		||||
      env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
 | 
			
		||||
 | 
			
		||||
    - os: linux
 | 
			
		||||
      compiler: g++
 | 
			
		||||
      env: CMAKE_SUBDIR_TEST=1
 | 
			
		||||
      script:
 | 
			
		||||
      - cd libs/smart_ptr/test/cmake_subdir_test && mkdir __build__ && cd __build__
 | 
			
		||||
      - cmake ..
 | 
			
		||||
      - cmake --build .
 | 
			
		||||
      - cmake --build . --target check
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
 | 
			
		||||
  - cd ..
 | 
			
		||||
  - git clone -b $BOOST_BRANCH 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
 | 
			
		||||
  - cp -r $TRAVIS_BUILD_DIR/* libs/smart_ptr
 | 
			
		||||
  - ./bootstrap.sh
 | 
			
		||||
  - ./b2 headers
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  - |-
 | 
			
		||||
    echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
 | 
			
		||||
  - ./b2 -j3 libs/smart_ptr/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
 | 
			
		||||
 | 
			
		||||
notifications:
 | 
			
		||||
  email:
 | 
			
		||||
    on_success: always
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
# Copyright 2018 Mike Dev
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
# Partial (add_subdirectory only) and experimental CMake support
 | 
			
		||||
# Subject to change; please do not rely on the contents of this file yet
 | 
			
		||||
 | 
			
		||||
cmake_minimum_required(VERSION 3.5)
 | 
			
		||||
project(BoostSmartPtr LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
add_library(boost_smart_ptr INTERFACE)
 | 
			
		||||
add_library(Boost::smart_ptr ALIAS boost_smart_ptr)
 | 
			
		||||
 | 
			
		||||
target_include_directories(boost_smart_ptr INTERFACE include)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(boost_smart_ptr
 | 
			
		||||
    INTERFACE
 | 
			
		||||
        Boost::assert
 | 
			
		||||
        Boost::config
 | 
			
		||||
        Boost::core
 | 
			
		||||
        Boost::move
 | 
			
		||||
        Boost::predef
 | 
			
		||||
        Boost::static_assert
 | 
			
		||||
        Boost::throw_exception
 | 
			
		||||
        Boost::type_traits
 | 
			
		||||
)
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
# Boost.SmartPtr
 | 
			
		||||
 | 
			
		||||
Branch   | Travis | Appveyor
 | 
			
		||||
---------|--------|---------
 | 
			
		||||
Develop  | [](https://travis-ci.org/boostorg/smart_ptr) | [](https://ci.appveyor.com/project/pdimov/smart-ptr)
 | 
			
		||||
Master   | [](https://travis-ci.org/boostorg/smart_ptr) | [](https://ci.appveyor.com/project/pdimov/smart-ptr)
 | 
			
		||||
							
								
								
									
										76
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								appveyor.yml
									
									
									
									
									
								
							@@ -1,76 +0,0 @@
 | 
			
		||||
# Copyright 2016-2018 Peter Dimov
 | 
			
		||||
# Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
version: 1.0.{build}-{branch}
 | 
			
		||||
 | 
			
		||||
shallow_clone: true
 | 
			
		||||
 | 
			
		||||
branches:
 | 
			
		||||
  only:
 | 
			
		||||
    - master
 | 
			
		||||
    - develop
 | 
			
		||||
    - /feature\/.*/
 | 
			
		||||
 | 
			
		||||
environment:
 | 
			
		||||
  matrix:
 | 
			
		||||
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
 | 
			
		||||
      TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
 | 
			
		||||
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
 | 
			
		||||
      TOOLSET: msvc-14.0
 | 
			
		||||
      ADDRMD: 32,64
 | 
			
		||||
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
 | 
			
		||||
      TOOLSET: msvc-14.1
 | 
			
		||||
      CXXSTD: 14,17
 | 
			
		||||
      ADDRMD: 32,64
 | 
			
		||||
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
 | 
			
		||||
      ADDPATH: C:\cygwin\bin;
 | 
			
		||||
      TOOLSET: gcc
 | 
			
		||||
      CXXSTD: 03,11,14,1z
 | 
			
		||||
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
 | 
			
		||||
      ADDPATH: C:\cygwin64\bin;
 | 
			
		||||
      TOOLSET: gcc
 | 
			
		||||
      CXXSTD: 03,11,14,1z
 | 
			
		||||
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
 | 
			
		||||
      ADDPATH: C:\mingw\bin;
 | 
			
		||||
      TOOLSET: gcc
 | 
			
		||||
      CXXSTD: 03,11,14,1z
 | 
			
		||||
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
 | 
			
		||||
      ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;
 | 
			
		||||
      TOOLSET: gcc
 | 
			
		||||
      CXXSTD: 03,11,14,1z
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - set BOOST_BRANCH=develop
 | 
			
		||||
  - if "%APPVEYOR_REPO_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 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\
 | 
			
		||||
  - cmd /c bootstrap
 | 
			
		||||
  - b2 -d0 headers
 | 
			
		||||
 | 
			
		||||
build: off
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										2
									
								
								doc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								doc/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
/html/
 | 
			
		||||
/pdf/
 | 
			
		||||
							
								
								
									
										26
									
								
								doc/Jamfile
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								doc/Jamfile
									
									
									
									
									
								
							@@ -1,26 +0,0 @@
 | 
			
		||||
# Copyright 2017 Peter Dimov
 | 
			
		||||
# 
 | 
			
		||||
# Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
#
 | 
			
		||||
# See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
# http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
project doc/smart_ptr ;
 | 
			
		||||
 | 
			
		||||
import asciidoctor ;
 | 
			
		||||
 | 
			
		||||
html smart_ptr.html : smart_ptr.adoc ;
 | 
			
		||||
 | 
			
		||||
install html_ : smart_ptr.html : <location>html ;
 | 
			
		||||
 | 
			
		||||
pdf smart_ptr.pdf : smart_ptr.adoc ;
 | 
			
		||||
explicit smart_ptr.pdf ;
 | 
			
		||||
 | 
			
		||||
install pdf_ : smart_ptr.pdf : <location>pdf ;
 | 
			
		||||
explicit pdf_ ;
 | 
			
		||||
 | 
			
		||||
###############################################################################
 | 
			
		||||
alias boostdoc ;
 | 
			
		||||
explicit boostdoc ;
 | 
			
		||||
alias boostrelease : html_ ;
 | 
			
		||||
explicit boostrelease ;
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
<style>
 | 
			
		||||
 | 
			
		||||
*:not(pre)>code { background: none; color: #600000; }
 | 
			
		||||
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,76 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
# Boost.SmartPtr: The Smart Pointer Library
 | 
			
		||||
Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes
 | 
			
		||||
:toc: left
 | 
			
		||||
:toclevels: 2
 | 
			
		||||
:idprefix:
 | 
			
		||||
:listing-caption: Code Example
 | 
			
		||||
:docinfo: private-footer
 | 
			
		||||
 | 
			
		||||
:leveloffset: +1
 | 
			
		||||
 | 
			
		||||
include::smart_ptr/introduction.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/make_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[]
 | 
			
		||||
 | 
			
		||||
// appendix
 | 
			
		||||
include::smart_ptr/techniques.adoc[]
 | 
			
		||||
 | 
			
		||||
// appendix
 | 
			
		||||
include::smart_ptr/history.adoc[]
 | 
			
		||||
 | 
			
		||||
// appendix, deprecated
 | 
			
		||||
include::smart_ptr/shared_array.adoc[]
 | 
			
		||||
 | 
			
		||||
:leveloffset: -1
 | 
			
		||||
 | 
			
		||||
[[copyright]]
 | 
			
		||||
[appendix]
 | 
			
		||||
## Copyright and License
 | 
			
		||||
 | 
			
		||||
This documentation is
 | 
			
		||||
 | 
			
		||||
* Copyright 1999 Greg Colvin
 | 
			
		||||
* Copyright 1999 Beman Dawes
 | 
			
		||||
* Copyright 2002 Darin Adler
 | 
			
		||||
* Copyright 2003-2017 Peter Dimov
 | 
			
		||||
* Copyright 2005, 2006 Ion Gaztañaga
 | 
			
		||||
* Copyright 2008 Frank Mori Hess
 | 
			
		||||
* Copyright 2012-2017 Glen Fernandes
 | 
			
		||||
* Copyright 2013 Andrey Semashev
 | 
			
		||||
 | 
			
		||||
and is distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].
 | 
			
		||||
@@ -1,170 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#atomic_shared_ptr]
 | 
			
		||||
# atomic_shared_ptr
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: atomic_shared_ptr_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The class template `atomic_shared_ptr<T>` implements the interface of `std::atomic`
 | 
			
		||||
for a contained value of type `shared_ptr<T>`. Concurrent access to `atomic_shared_ptr`
 | 
			
		||||
is not a data race.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`atomic_shared_ptr` is defined in `<boost/smart_ptr/atomic_shared_ptr.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class atomic_shared_ptr {
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> p_; // exposition only
 | 
			
		||||
 | 
			
		||||
    atomic_shared_ptr(const atomic_shared_ptr&) = delete;
 | 
			
		||||
    atomic_shared_ptr& operator=(const atomic_shared_ptr&) = delete;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    constexpr atomic_shared_ptr() noexcept;
 | 
			
		||||
    atomic_shared_ptr( shared_ptr<T> p ) noexcept;
 | 
			
		||||
 | 
			
		||||
    atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;
 | 
			
		||||
 | 
			
		||||
    bool is_lock_free() const noexcept;
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> load( int = 0 ) const noexcept;
 | 
			
		||||
    operator shared_ptr<T>() const noexcept;
 | 
			
		||||
 | 
			
		||||
    void store( shared_ptr<T> r, int = 0 ) noexcept;
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) noexcept;
 | 
			
		||||
 | 
			
		||||
    bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;
 | 
			
		||||
    bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;
 | 
			
		||||
    bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;
 | 
			
		||||
    bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;
 | 
			
		||||
 | 
			
		||||
    bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;
 | 
			
		||||
    bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;
 | 
			
		||||
    bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;
 | 
			
		||||
    bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
constexpr atomic_shared_ptr() noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Default-initializes `p_`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
atomic_shared_ptr( shared_ptr<T> p ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Initializes `p_` to `p`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: `p_.swap(r)`.
 | 
			
		||||
Returns:: `*this`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
bool is_lock_free() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `false`.
 | 
			
		||||
 | 
			
		||||
NOTE: This implementation is not lock-free.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<T> load( int = 0 ) const noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
operator shared_ptr<T>() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `p_`.
 | 
			
		||||
 | 
			
		||||
NOTE: The `int` argument is intended to be of type `memory_order`, but is ignored.
 | 
			
		||||
  This implementation is lock-based and therefore always sequentially consistent.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
void store( shared_ptr<T> r, int = 0 ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: `p_.swap(r)`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: `p_.swap(r)`.
 | 
			
		||||
Returns:: The old value of `p_`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: If `p_` is equivalent to `v`, assigns `w` to `p_`, otherwise assigns `p_` to `v`.
 | 
			
		||||
Returns:: `true` if `p_` was equivalent to `v`, `false` otherwise.
 | 
			
		||||
Remarks:: Two `shared_ptr` instances are equivalent if they store the same pointer value and _share ownership_.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: If `p_` is equivalent to `v`, assigns `std::move(w)` to `p_`, otherwise assigns `p_` to `v`.
 | 
			
		||||
Returns:: `true` if `p_` was equivalent to `v`, `false` otherwise.
 | 
			
		||||
Remarks:: The old value of `w` is not preserved in either case.
 | 
			
		||||
@@ -1,144 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2002, 2003, 2015, 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#enable_shared_from_this]
 | 
			
		||||
# enable_shared_from_this
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: enable_shared_from_this_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The class template `enable_shared_from_this` is used as a base class that allows
 | 
			
		||||
a `shared_ptr` or a `weak_ptr` to the current object to be obtained from within a
 | 
			
		||||
member function.
 | 
			
		||||
 | 
			
		||||
`enable_shared_from_this<T>` defines two member functions called `shared_from_this`
 | 
			
		||||
that return a `shared_ptr<T>` and `shared_ptr<T const>`, depending on constness, to
 | 
			
		||||
`this`. It also defines two member functions called `weak_from_this` that return a
 | 
			
		||||
corresponding `weak_ptr`.
 | 
			
		||||
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
#include <boost/enable_shared_from_this.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
class Y: public boost::enable_shared_from_this<Y>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    boost::shared_ptr<Y> f()
 | 
			
		||||
    {
 | 
			
		||||
        return shared_from_this();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr<Y> p(new Y);
 | 
			
		||||
    boost::shared_ptr<Y> q = p->f();
 | 
			
		||||
    assert(p == q);
 | 
			
		||||
    assert(!(p < q || q < p)); // p and q must share ownership
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`enable_shared_from_this` is defined in `<boost/smart_ptr/enable_shared_from_this.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class enable_shared_from_this {
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    // exposition only
 | 
			
		||||
    weak_ptr<T> weak_this_;
 | 
			
		||||
 | 
			
		||||
  protected:
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this() = default;
 | 
			
		||||
    ~enable_shared_from_this() = default;
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this(const enable_shared_from_this&) noexcept;
 | 
			
		||||
    enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> shared_from_this();
 | 
			
		||||
    shared_ptr<T const> shared_from_this() const;
 | 
			
		||||
 | 
			
		||||
    weak_ptr<T> weak_from_this() noexcept;
 | 
			
		||||
    weak_ptr<T const> weak_from_this() const noexcept;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
enable_shared_from_this(enable_shared_from_this const &) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Default-constructs `weak_this_`.
 | 
			
		||||
 | 
			
		||||
NOTE: `weak_this_` is _not_ copied from the argument.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
enable_shared_from_this& operator=(enable_shared_from_this const &) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `*this`.
 | 
			
		||||
 | 
			
		||||
NOTE: `weak_this_` is unchanged.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> shared_ptr<T> shared_from_this();
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T> shared_ptr<T const> shared_from_this() const;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `shared_ptr<T>(weak_this_)`.
 | 
			
		||||
 | 
			
		||||
NOTE: These members throw `bad_weak_ptr` when `*this` is not owned by a `shared_ptr`.
 | 
			
		||||
 | 
			
		||||
[NOTE]
 | 
			
		||||
====
 | 
			
		||||
`weak_this_` is initialized by `shared_ptr` to a copy of itself when it's constructed by a pointer to `*this`.
 | 
			
		||||
For example, in the following code:
 | 
			
		||||
```
 | 
			
		||||
class Y: public boost::enable_shared_from_this<Y> {};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr<Y> p(new Y);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
the construction of `p` will automatically initialize `p\->weak_this_` to `p`.
 | 
			
		||||
====
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> weak_ptr<T> weak_from_this() noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T> weak_ptr<T const> weak_from_this() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `weak_this_`.
 | 
			
		||||
@@ -1,113 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 1999 Greg Colvin and Beman Dawes
 | 
			
		||||
Copyright 2002 Darin Adler
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[[history]]
 | 
			
		||||
[appendix]
 | 
			
		||||
# History and Acknowledgments
 | 
			
		||||
:idprefix: history_
 | 
			
		||||
 | 
			
		||||
## Summer 1994
 | 
			
		||||
 | 
			
		||||
Greg Colvin http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf[proposed]
 | 
			
		||||
to the {cpp} Standards Committee classes named `auto_ptr` and `counted_ptr` which were very
 | 
			
		||||
similar to what we now call `scoped_ptr` and `shared_ptr`. In one of the very few cases
 | 
			
		||||
where the Library Working Group's recommendations were not followed by the full committee,
 | 
			
		||||
`counted_ptr` was rejected and surprising transfer-of-ownership semantics were added to `auto_ptr`.
 | 
			
		||||
 | 
			
		||||
## October 1998
 | 
			
		||||
 | 
			
		||||
Beman Dawes proposed reviving the original semantics under the names `safe_ptr` and `counted_ptr`,
 | 
			
		||||
meeting of Per Andersson, Matt Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis,
 | 
			
		||||
Dietmar Kühl, Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new class
 | 
			
		||||
names were finalized, it was decided that there was no need to exactly follow the `std::auto_ptr`
 | 
			
		||||
interface, and various function signatures and semantics were finalized.
 | 
			
		||||
 | 
			
		||||
Over the next three months, several implementations were considered for `shared_ptr`, and discussed
 | 
			
		||||
on the http://www.boost.org/[boost.org] mailing list. The implementation questions revolved around
 | 
			
		||||
the reference count which must be kept, either attached to the pointed to object, or detached elsewhere.
 | 
			
		||||
Each of those variants have themselves two major variants:
 | 
			
		||||
 | 
			
		||||
* Direct detached: the `shared_ptr` contains a pointer to the object, and a pointer to the count. 
 | 
			
		||||
* Indirect detached: the `shared_ptr` contains a pointer to a helper object, which in turn contains a pointer to the object and the count. 
 | 
			
		||||
* Embedded attached: the count is a member of the object pointed to. 
 | 
			
		||||
* Placement attached: the count is attached via operator new manipulations.
 | 
			
		||||
 | 
			
		||||
Each implementation technique has advantages and disadvantages. We went so far as to run various timings
 | 
			
		||||
of the direct and indirect approaches, and found that at least on Intel Pentium chips there was very little
 | 
			
		||||
measurable difference. Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar Kühl
 | 
			
		||||
suggested an elegant partial template specialization technique to allow users to choose which implementation
 | 
			
		||||
they preferred, and that was also experimented with.
 | 
			
		||||
 | 
			
		||||
But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage users", and in the end we choose
 | 
			
		||||
to supply only the direct implementation.
 | 
			
		||||
 | 
			
		||||
## May 1999
 | 
			
		||||
 | 
			
		||||
In April and May, 1999, Valentin Bonnard and David Abrahams made a number of suggestions resulting in numerous improvements.
 | 
			
		||||
 | 
			
		||||
## September 1999
 | 
			
		||||
 | 
			
		||||
Luis Coelho provided `shared_ptr::swap` and `shared_array::swap`.
 | 
			
		||||
 | 
			
		||||
## November 1999
 | 
			
		||||
 | 
			
		||||
Darin Adler provided `operator ==`, `operator !=`, and `std::swap` and `std::less` specializations for shared types.
 | 
			
		||||
 | 
			
		||||
## May 2001
 | 
			
		||||
 | 
			
		||||
Vladimir Prus suggested requiring a complete type on destruction. Refinement evolved in discussions including Dave Abrahams,
 | 
			
		||||
Greg Colvin, Beman Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and others.
 | 
			
		||||
 | 
			
		||||
## January 2002
 | 
			
		||||
 | 
			
		||||
Peter Dimov reworked all four classes, adding features, fixing bugs, splitting them into four separate headers, and adding
 | 
			
		||||
`weak_ptr`.
 | 
			
		||||
 | 
			
		||||
## March 2003
 | 
			
		||||
 | 
			
		||||
Peter Dimov, Beman Dawes and Greg Colvin http://open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html[proposed] `shared_ptr`
 | 
			
		||||
and `weak_ptr` for inclusion in the Standard Library via the first Library Technical Report (known as TR1). The proposal was
 | 
			
		||||
accepted and eventually went on to become a part of the {cpp} standard in its 2011 iteration.
 | 
			
		||||
 | 
			
		||||
## July 2007
 | 
			
		||||
 | 
			
		||||
Peter Dimov and Beman Dawes http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm[proposed] a number of enhancements
 | 
			
		||||
to `shared_ptr` as it was entering the working paper that eventually became the {cpp}11 standard.
 | 
			
		||||
 | 
			
		||||
## November 2012
 | 
			
		||||
 | 
			
		||||
Glen Fernandes provided implementations of `make_shared` and `allocate_shared` for arrays. They achieve a single allocation
 | 
			
		||||
for an array that can be initialized with constructor arguments or initializer lists as well as overloads for default initialization
 | 
			
		||||
and no value initialization.
 | 
			
		||||
 | 
			
		||||
Peter Dimov aided this development by extending `shared_ptr` to support arrays via the syntax `shared_ptr<T[]>` and `shared_ptr<T[N]>`.
 | 
			
		||||
 | 
			
		||||
## April 2013
 | 
			
		||||
 | 
			
		||||
Peter Dimov http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3640.html[proposed] the extension of `shared_ptr` to support
 | 
			
		||||
arrays for inclusion into the standard, and it was accepted.
 | 
			
		||||
 | 
			
		||||
## February 2014
 | 
			
		||||
 | 
			
		||||
Glen Fernandes updated `make_shared` and `allocate_shared` to conform to the specification in {cpp} standard paper
 | 
			
		||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html[N3870], and implemented `make_unique` for arrays and objects.
 | 
			
		||||
 | 
			
		||||
Peter Dimov and Glen Fernandes updated the scalar and array implementations, respectively, to resolve {cpp} standard library defect 2070.
 | 
			
		||||
 | 
			
		||||
## February 2017
 | 
			
		||||
 | 
			
		||||
Glen Fernandes rewrote `allocate_shared` and `make_shared` for arrays for a more optimal and more maintainable implementation.
 | 
			
		||||
 | 
			
		||||
## June 2017
 | 
			
		||||
 | 
			
		||||
Peter Dimov and Glen Fernandes rewrote the documentation in Asciidoc format.
 | 
			
		||||
 | 
			
		||||
Peter Dimov added `atomic_shared_ptr` and `local_shared_ptr`.
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 1999 Greg Colvin and Beman Dawes
 | 
			
		||||
Copyright 2002 Darin Adler
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#introduction]
 | 
			
		||||
# Introduction
 | 
			
		||||
:idprefix: intro
 | 
			
		||||
 | 
			
		||||
Smart pointers are objects which store pointers to dynamically allocated (heap) objects.
 | 
			
		||||
They behave much like built-in {cpp} pointers except that they automatically delete the object
 | 
			
		||||
pointed to at the appropriate time. Smart pointers are particularly useful in the face of
 | 
			
		||||
exceptions as they ensure proper destruction of dynamically allocated objects. They can also be
 | 
			
		||||
used to keep track of dynamically allocated objects shared by multiple owners.
 | 
			
		||||
 | 
			
		||||
Conceptually, smart pointers are seen as owning the object pointed to, and thus responsible for
 | 
			
		||||
deletion of the object when it is no longer needed. As such, they are examples of the "resource
 | 
			
		||||
acquisition is initialization" idiom described in Bjarne Stroustrup's "The C++ Programming Language",
 | 
			
		||||
3rd edition, Section 14.4, Resource Management.
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
* `<<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.
 | 
			
		||||
 | 
			
		||||
`shared_ptr` and `weak_ptr` are part of the {cpp} standard since its 2011 iteration.
 | 
			
		||||
 | 
			
		||||
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_unique,make_unique>>`, a factory function returning `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`;
 | 
			
		||||
* `<<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.
 | 
			
		||||
* `<<atomic_shared_ptr,atomic_shared_ptr>>`, a helper class implementing the interface of `std::atomic` for a value of type `shared_ptr`.
 | 
			
		||||
 | 
			
		||||
As a general rule, the destructor or `operator delete` for an object managed by pointers in the library
 | 
			
		||||
are not allowed to throw exceptions.
 | 
			
		||||
@@ -1,478 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2003-2005, 2013, 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#intrusive_ptr]
 | 
			
		||||
# intrusive_ptr: Managing Objects with Embedded Counts
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: intrusive_ptr_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The `intrusive_ptr` class template stores a pointer to an object with an embedded reference count.
 | 
			
		||||
Every new `intrusive_ptr` instance increments the reference count by using an unqualified call to the
 | 
			
		||||
function `intrusive_ptr_add_ref`, passing it the pointer as an argument. Similarly, when an `intrusive_ptr`
 | 
			
		||||
is destroyed, it calls `intrusive_ptr_release`; this function is responsible for destroying the object when
 | 
			
		||||
its reference count drops to zero. The user is expected to provide suitable definitions of these two functions.
 | 
			
		||||
On compilers that support argument-dependent lookup, `intrusive_ptr_add_ref` and `intrusive_ptr_release` should
 | 
			
		||||
be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in namespace
 | 
			
		||||
`boost`. The library provides a helper base class template `<<intrusive_ref_counter,intrusive_ref_counter>>` which
 | 
			
		||||
may help adding support for `intrusive_ptr` to user types.
 | 
			
		||||
 | 
			
		||||
The class template is parameterized on `T`, the type of the object pointed to. `intrusive_ptr<T>` can be implicitly
 | 
			
		||||
converted to `intrusive_ptr<U>` whenever `T*` can be implicitly converted to `U*`.
 | 
			
		||||
 | 
			
		||||
The main reasons to use `intrusive_ptr` are:
 | 
			
		||||
 | 
			
		||||
* Some existing frameworks or OSes provide objects with embedded reference counts;
 | 
			
		||||
* The memory footprint of `intrusive_ptr` is the same as the corresponding raw pointer;
 | 
			
		||||
* `intrusive_ptr<T>` can be constructed from an arbitrary raw pointer of type `T*`.
 | 
			
		||||
 | 
			
		||||
As a general rule, if it isn't obvious whether `intrusive_ptr` better fits your needs than `shared_ptr`, try a `shared_ptr`-based design first.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`intrusive_ptr` is defined in `<boost/smart_ptr/intrusive_ptr.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class intrusive_ptr {
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr() noexcept;
 | 
			
		||||
    intrusive_ptr(T * p, bool add_ref = true);
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(intrusive_ptr const & r);
 | 
			
		||||
    template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(intrusive_ptr && r);
 | 
			
		||||
    template<class Y> intrusive_ptr(intrusive_ptr<Y> && r);
 | 
			
		||||
 | 
			
		||||
    ~intrusive_ptr();
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr & operator=(intrusive_ptr const & r);
 | 
			
		||||
    template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
 | 
			
		||||
    intrusive_ptr & operator=(T * r);
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr & operator=(intrusive_ptr && r);
 | 
			
		||||
    template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> && r);
 | 
			
		||||
 | 
			
		||||
    void reset();
 | 
			
		||||
    void reset(T * r);
 | 
			
		||||
    void reset(T * r, bool add_ref);
 | 
			
		||||
 | 
			
		||||
    T & operator*() const noexcept;
 | 
			
		||||
    T * operator->() const noexcept;
 | 
			
		||||
    T * get() const noexcept;
 | 
			
		||||
    T * detach() noexcept;
 | 
			
		||||
 | 
			
		||||
    explicit operator bool () const noexcept;
 | 
			
		||||
 | 
			
		||||
    void swap(intrusive_ptr & b) noexept;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator==(intrusive_ptr<T> const & a, U * b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator!=(intrusive_ptr<T> const & a, U * b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator==(T * a, intrusive_ptr<U> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T> T * get_pointer(intrusive_ptr<T> const & p) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class E, class T, class Y>
 | 
			
		||||
    std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os,
 | 
			
		||||
      intrusive_ptr<Y> const & p);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
### element_type
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
typedef T element_type;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Provides the type of the template parameter T.
 | 
			
		||||
 | 
			
		||||
### constructors
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
intrusive_ptr() noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Postconditions:: `get() == 0`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
intrusive_ptr(T * p, bool add_ref = true);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: `if(p != 0 && add_ref) intrusive_ptr_add_ref(p);`.
 | 
			
		||||
Postconditions:: `get() == p`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
intrusive_ptr(intrusive_ptr const & r);
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: `T * p = r.get(); if(p != 0) intrusive_ptr_add_ref(p);`.
 | 
			
		||||
Postconditions:: `get() == r.get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
intrusive_ptr(intrusive_ptr && r);
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> intrusive_ptr(intrusive_ptr<Y> && r);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Postconditions:: `get()` equals the old value of `r.get()`. `r.get() == 0`.
 | 
			
		||||
 | 
			
		||||
### destructor
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
~intrusive_ptr();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: `if(get() != 0) intrusive_ptr_release(get());`.
 | 
			
		||||
 | 
			
		||||
### assignment
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
intrusive_ptr & operator=(intrusive_ptr const & r);
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
intrusive_ptr & operator=(T * r);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `intrusive_ptr(r).swap(*this)`.
 | 
			
		||||
Returns:: `*this`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
intrusive_ptr & operator=(intrusive_ptr && r);
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> && r);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `intrusive_ptr(std::move(r)).swap(*this)`.
 | 
			
		||||
Returns:: `*this`.
 | 
			
		||||
 | 
			
		||||
### reset
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
void reset();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `intrusive_ptr().swap(*this)`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
void reset(T * r);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `intrusive_ptr(r).swap(*this)`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
void reset(T * r, bool add_ref);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`.
 | 
			
		||||
 | 
			
		||||
### indirection
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
T & operator*() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requirements:: `get() != 0`.
 | 
			
		||||
Returns:: `*get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
T * operator->() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requirements:: `get() != 0`.
 | 
			
		||||
Returns:: `get()`.
 | 
			
		||||
 | 
			
		||||
### get
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
T * get() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: the stored pointer.
 | 
			
		||||
 | 
			
		||||
### detach
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
T * detach() noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: the stored pointer.
 | 
			
		||||
Postconditions:: `get() == 0`.
 | 
			
		||||
 | 
			
		||||
NOTE: The returned pointer has an elevated reference count. This allows conversion of an `intrusive_ptr`
 | 
			
		||||
back to a raw pointer, without the performance overhead of acquiring and dropping an extra reference.
 | 
			
		||||
It can be viewed as the complement of the non-reference-incrementing constructor.
 | 
			
		||||
 | 
			
		||||
CAUTION: Using `detach` escapes the safety of automatic reference counting provided by `intrusive_ptr`.
 | 
			
		||||
It should by used only where strictly necessary (such as when interfacing to an existing API), and when
 | 
			
		||||
the implications are thoroughly understood.
 | 
			
		||||
 | 
			
		||||
### conversions
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
explicit operator bool () const noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `get() != 0`.
 | 
			
		||||
 | 
			
		||||
NOTE: This conversion operator allows `intrusive_ptr` objects to be used in boolean contexts,
 | 
			
		||||
like `if (p && p\->valid()) {}`.
 | 
			
		||||
 | 
			
		||||
NOTE: On C++03 compilers, the return value is of an unspecified type.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
void swap(intrusive_ptr & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Exchanges the contents of the two smart pointers.
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
### comparison
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `a.get() == b.get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `a.get() != b.get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator==(intrusive_ptr<T> const & a, U * b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `a.get() == b`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator!=(intrusive_ptr<T> const & a, U * b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `a.get() != b`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator==(T * a, intrusive_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `a == b.get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `a != b.get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `std::less<T *>()(a.get(), b.get())`.
 | 
			
		||||
 | 
			
		||||
NOTE: Allows `intrusive_ptr` objects to be used as keys in associative containers.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `a.swap(b)`.
 | 
			
		||||
 | 
			
		||||
### get_pointer
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> T * get_pointer(intrusive_ptr<T> const & p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `p.get()`.
 | 
			
		||||
 | 
			
		||||
NOTE: Provided as an aid to generic programming. Used by `mem_fn`.
 | 
			
		||||
 | 
			
		||||
### static_pointer_cast
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `intrusive_ptr<T>(static_cast<T*>(r.get()))`.
 | 
			
		||||
 | 
			
		||||
### const_pointer_cast
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `intrusive_ptr<T>(const_cast<T*>(r.get()))`.
 | 
			
		||||
 | 
			
		||||
### dynamic_pointer_cast
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `intrusive_ptr<T>(dynamic_cast<T*>(r.get()))`.
 | 
			
		||||
 | 
			
		||||
### operator<<
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class E, class T, class Y>
 | 
			
		||||
  std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os,
 | 
			
		||||
    intrusive_ptr<Y> const & p);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: `os << p.get();`.
 | 
			
		||||
Returns:: `os`.
 | 
			
		||||
@@ -1,142 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
Copyright 2013 Andrey Semashev
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#intrusive_ref_counter]
 | 
			
		||||
# intrusive_ref_counter
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: intrusive_ref_counter_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The `intrusive_ref_counter` class template implements a reference counter for
 | 
			
		||||
a derived user's class that is intended to be used with `intrusive_ptr`. The
 | 
			
		||||
base class has associated `intrusive_ptr_add_ref` and `intrusive_ptr_release`
 | 
			
		||||
functions which modify the reference counter as needed and destroy the user's
 | 
			
		||||
object when the counter drops to zero.
 | 
			
		||||
 | 
			
		||||
The class template is parameterized on `Derived` and `CounterPolicy`
 | 
			
		||||
parameters. The first parameter is the user's class that derives from
 | 
			
		||||
`intrusive_ref_counter`. This type is needed in order to destroy the object
 | 
			
		||||
correctly when there are no references to it left.
 | 
			
		||||
 | 
			
		||||
The second parameter is a policy that defines the nature of the reference
 | 
			
		||||
counter. The library provides two such policies: `thread_unsafe_counter` and
 | 
			
		||||
`thread_safe_counter`. The former instructs the `intrusive_ref_counter` base
 | 
			
		||||
class to use a counter only suitable for a single-threaded use. Pointers to a
 | 
			
		||||
single object that uses this kind of reference counter must not be used in
 | 
			
		||||
different threads. The latter policy makes the reference counter thread-safe,
 | 
			
		||||
unless the target platform doesn't support threading. Since in modern systems
 | 
			
		||||
support for threading is common, the default counter policy is
 | 
			
		||||
`thread_safe_counter`.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`intrusive_ref_counter` is defined in
 | 
			
		||||
`<boost/smart_ptr/intrusive_ref_counter.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
  struct thread_unsafe_counter;
 | 
			
		||||
  struct thread_safe_counter;
 | 
			
		||||
 | 
			
		||||
  template<class Derived, class CounterPolicy = thread_safe_counter>
 | 
			
		||||
  class intrusive_ref_counter {
 | 
			
		||||
  public:
 | 
			
		||||
    intrusive_ref_counter() noexcept;
 | 
			
		||||
    intrusive_ref_counter(const intrusive_ref_counter& v) noexcept;
 | 
			
		||||
 | 
			
		||||
    intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
 | 
			
		||||
 | 
			
		||||
    unsigned int use_count() const noexcept;
 | 
			
		||||
 | 
			
		||||
  protected:
 | 
			
		||||
    ~intrusive_ref_counter() = default;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class Derived, class CounterPolicy>
 | 
			
		||||
    void intrusive_ptr_add_ref(
 | 
			
		||||
      const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class Derived, class CounterPolicy>
 | 
			
		||||
    void intrusive_ptr_release(
 | 
			
		||||
      const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
### Constructors
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
intrusive_ref_counter() noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
```
 | 
			
		||||
intrusive_ref_counter(const intrusive_ref_counter&) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Postconditions::: `use_count() == 0`.
 | 
			
		||||
 | 
			
		||||
NOTE: The pointer to the constructed object is expected to be passed to
 | 
			
		||||
`intrusive_ptr` constructor, assignment operator or `reset` method, which
 | 
			
		||||
would increment the reference counter.
 | 
			
		||||
 | 
			
		||||
### Destructor
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
~intrusive_ref_counter();
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Destroys the counter object.
 | 
			
		||||
 | 
			
		||||
NOTE: The destructor is protected so that the object can only be destroyed
 | 
			
		||||
through the `Derived` class.
 | 
			
		||||
 | 
			
		||||
### Assignment
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Does nothing, reference counter is not modified.
 | 
			
		||||
 | 
			
		||||
### use_count
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
unsigned int use_count() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: The current value of the reference counter.
 | 
			
		||||
 | 
			
		||||
NOTE: The returned value may not be actual in multi-threaded applications.
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
### intrusive_ptr_add_ref
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Derived, class CounterPolicy>
 | 
			
		||||
  void intrusive_ptr_add_ref(
 | 
			
		||||
    const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Increments the reference counter.
 | 
			
		||||
 | 
			
		||||
### intrusive_ptr_release
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Derived, class CounterPolicy>
 | 
			
		||||
  void intrusive_ptr_release(
 | 
			
		||||
    const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Decrements the reference counter. If the reference counter reaches
 | 
			
		||||
0, calls `delete static_cast<const Derived*>(p)`.
 | 
			
		||||
@@ -1,719 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#local_shared_ptr]
 | 
			
		||||
# local_shared_ptr: Shared Ownership within a Single Thread
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: local_shared_ptr_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
`local_shared_ptr` is nearly identical to `shared_ptr`, with the only difference of note being that its reference count is
 | 
			
		||||
updated with non-atomic operations. As such, a `local_shared_ptr` and all its copies must reside in (be local to) a single
 | 
			
		||||
thread (hence the name.)
 | 
			
		||||
 | 
			
		||||
`local_shared_ptr` can be converted to `shared_ptr` and vice versa. Creating a `local_shared_ptr` from a `shared_ptr` creates
 | 
			
		||||
a new local reference count; this means that two `local_shared_ptr` instances, both created from the same `shared_ptr`, refer
 | 
			
		||||
to the same object but don't share the same count, and as such, can safely be used by two different threads.
 | 
			
		||||
 | 
			
		||||
.Two local_shared_ptr instances created from a shared_ptr
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<X> p1( new X );
 | 
			
		||||
 | 
			
		||||
local_shared_ptr<X> p2( p1 ); // p2.local_use_count() == 1
 | 
			
		||||
local_shared_ptr<X> p3( p1 ); // p3.local_use_count() also 1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Creating the second `local_shared_ptr` from the first one, however, does lead to the two sharing the same count:
 | 
			
		||||
 | 
			
		||||
.A local_shared_ptr created from another local_shared_ptr
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<X> p1( new X );
 | 
			
		||||
 | 
			
		||||
local_shared_ptr<X> p2( p1 ); // p2.local_use_count() == 1
 | 
			
		||||
local_shared_ptr<X> p3( p2 ); // p3.local_use_count() == 2
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Two `shared_ptr` instances created from the same `local_shared_ptr` do share ownership:
 | 
			
		||||
 | 
			
		||||
.Two shared_ptr instances created from a local_shared_ptr
 | 
			
		||||
```
 | 
			
		||||
local_shared_ptr<X> p1( new X );
 | 
			
		||||
 | 
			
		||||
shared_ptr<X> p2( p1 ); // p2.use_count() == 2
 | 
			
		||||
shared_ptr<X> p3( p1 ); // p3.use_count() == 3
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Here `p2.use_count()` is 2, because `p1` holds a reference, too.
 | 
			
		||||
 | 
			
		||||
One can think of `local_shared_ptr<T>` as `shared_ptr<shared_ptr<T>>`, with the outer `shared_ptr` using non-atomic operations for
 | 
			
		||||
its count. Converting from `local_shared_ptr` to `shared_ptr` gives you a copy of the inner `shared_ptr`; converting from `shared_ptr`
 | 
			
		||||
wraps it into an outer `shared_ptr` with a non-atomic use count (conceptually speaking) and returns the result.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`local_shared_ptr` is defined in `<boost/smart_ptr/local_shared_ptr.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class local_shared_ptr {
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    typedef /*see below*/ element_type;
 | 
			
		||||
 | 
			
		||||
    // constructors
 | 
			
		||||
 | 
			
		||||
    constexpr local_shared_ptr() noexcept;
 | 
			
		||||
    constexpr local_shared_ptr(std::nullptr_t) noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class Y> explicit local_shared_ptr(Y * p);
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> local_shared_ptr(Y * p, D d);
 | 
			
		||||
    template<class D> local_shared_ptr(std::nullptr_t p, D d);
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D, class A> local_shared_ptr(Y * p, D d, A a);
 | 
			
		||||
    template<class D, class A> local_shared_ptr(std::nullptr_t p, D d, A a);
 | 
			
		||||
 | 
			
		||||
    local_shared_ptr(local_shared_ptr const & r) noexcept;
 | 
			
		||||
    template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
    local_shared_ptr(local_shared_ptr && r) noexcept;
 | 
			
		||||
    template<class Y> local_shared_ptr(local_shared_ptr<Y> && r) noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class Y> local_shared_ptr( shared_ptr<Y> const & r );
 | 
			
		||||
    template<class Y> local_shared_ptr( shared_ptr<Y> && r );
 | 
			
		||||
 | 
			
		||||
    template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r, element_type * p) noexcept;
 | 
			
		||||
    template<class Y> local_shared_ptr(local_shared_ptr<Y> && r, element_type * p) noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> local_shared_ptr(std::unique_ptr<Y, D> && r);
 | 
			
		||||
    
 | 
			
		||||
    // destructor
 | 
			
		||||
 | 
			
		||||
    ~local_shared_ptr() noexcept;
 | 
			
		||||
 | 
			
		||||
    // assignment
 | 
			
		||||
 | 
			
		||||
    local_shared_ptr & operator=(local_shared_ptr const & r) noexcept;
 | 
			
		||||
    template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
    local_shared_ptr & operator=(local_shared_ptr const && r) noexcept;
 | 
			
		||||
    template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const && r) noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> local_shared_ptr & operator=(std::unique_ptr<Y, D> && r);
 | 
			
		||||
 | 
			
		||||
    local_shared_ptr & operator=(std::nullptr_t) noexcept;
 | 
			
		||||
 | 
			
		||||
    // reset
 | 
			
		||||
	
 | 
			
		||||
    void reset() noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class Y> void reset(Y * p);
 | 
			
		||||
    template<class Y, class D> void reset(Y * p, D d);
 | 
			
		||||
    template<class Y, class D, class A> void reset(Y * p, D d, A a);
 | 
			
		||||
 | 
			
		||||
    template<class Y> void reset(local_shared_ptr<Y> const & r, element_type * p) noexcept;
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    // only valid when T is an array type
 | 
			
		||||
    element_type & operator[](std::ptrdiff_t i) const noexcept;
 | 
			
		||||
 | 
			
		||||
    element_type * get() const noexcept;
 | 
			
		||||
 | 
			
		||||
    long local_use_count() const noexcept;
 | 
			
		||||
 | 
			
		||||
    // conversions
 | 
			
		||||
 | 
			
		||||
    explicit operator bool() const noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class Y> operator shared_ptr<Y>() const noexcept;
 | 
			
		||||
    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;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // comparisons
 | 
			
		||||
  
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator==(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator==(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator==(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator!=(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator!=(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator!=(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T> bool operator==(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
 | 
			
		||||
  template<class T> bool operator==(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T> bool operator!=(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
 | 
			
		||||
  template<class T> bool operator!=(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  // swap
 | 
			
		||||
  
 | 
			
		||||
  template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  // get_pointer
 | 
			
		||||
  
 | 
			
		||||
  template<class T>
 | 
			
		||||
    typename local_shared_ptr<T>::element_type *
 | 
			
		||||
      get_pointer(local_shared_ptr<T> const & p) noexcept;
 | 
			
		||||
 | 
			
		||||
  // casts
 | 
			
		||||
  
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    local_shared_ptr<T> static_pointer_cast(local_shared_ptr<U> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    local_shared_ptr<T> const_pointer_cast(local_shared_ptr<U> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    local_shared_ptr<T> dynamic_pointer_cast(local_shared_ptr<U> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    local_shared_ptr<T> reinterpret_pointer_cast(local_shared_ptr<U> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
  // stream I/O
 | 
			
		||||
 | 
			
		||||
  template<class E, class T, class Y>
 | 
			
		||||
    std::basic_ostream<E, T> &
 | 
			
		||||
      operator<< (std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p);
 | 
			
		||||
 | 
			
		||||
  // get_deleter
 | 
			
		||||
  
 | 
			
		||||
  template<class D, class T> D * get_deleter(local_shared_ptr<T> const & p) noexcept;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
### element_type
 | 
			
		||||
```
 | 
			
		||||
typedef ... element_type;
 | 
			
		||||
```
 | 
			
		||||
`element_type` is `T` when `T` is not an array type, and `U` when `T` is `U[]` or `U[N]`.
 | 
			
		||||
 | 
			
		||||
### default constructor
 | 
			
		||||
```
 | 
			
		||||
constexpr local_shared_ptr() noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
constexpr local_shared_ptr(std::nullptr_t) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Constructs an empty `local_shared_ptr`.
 | 
			
		||||
Postconditions:: `local_use_count() == 0 && get() == 0`.
 | 
			
		||||
 | 
			
		||||
### pointer constructor
 | 
			
		||||
```
 | 
			
		||||
template<class Y> explicit local_shared_ptr(Y * p);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p )`.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `local_use_count() == 1 && get() == p`.
 | 
			
		||||
 | 
			
		||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
 | 
			
		||||
 | 
			
		||||
### constructors taking a deleter
 | 
			
		||||
```
 | 
			
		||||
template<class Y, class D> local_shared_ptr(Y * p, D d);
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class D> local_shared_ptr(std::nullptr_t p, D d);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p, d )`.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `local_use_count() == 1 && get() == p`.
 | 
			
		||||
 | 
			
		||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Y, class D, class A> local_shared_ptr(Y * p, D d, A a);
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class D, class A> local_shared_ptr(std::nullptr_t p, D d, A a);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p, d, a )`.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `local_use_count() == 1 && get() == p`.
 | 
			
		||||
 | 
			
		||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
 | 
			
		||||
 | 
			
		||||
### copy and converting constructors
 | 
			
		||||
```
 | 
			
		||||
local_shared_ptr(local_shared_ptr const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: `Y*` should be convertible to `T*`.
 | 
			
		||||
 | 
			
		||||
Effects:: If `r` is empty, constructs an empty `local_shared_ptr`; otherwise, constructs a `local_shared_ptr` that shares ownership with `r`.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `get() == r.get() && local_use_count() == r.local_use_count()`.
 | 
			
		||||
 | 
			
		||||
### move constructors
 | 
			
		||||
```
 | 
			
		||||
local_shared_ptr(local_shared_ptr && r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> && r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: `Y*` should be convertible to `T*`.
 | 
			
		||||
 | 
			
		||||
Effects:: Move-constructs a `local_shared_ptr` from `r`.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `*this` contains the old value of `r`. `r` is empty and `r.get() == 0`.
 | 
			
		||||
 | 
			
		||||
### shared_ptr constructor
 | 
			
		||||
```
 | 
			
		||||
template<class Y> local_shared_ptr( shared_ptr<Y> const & r );
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> local_shared_ptr( shared_ptr<Y> && r );
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Constructs a `local_shared_ptr` that owns `r`.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `local_use_count() == 1`. `get()` returns the old value of `r.get()`.
 | 
			
		||||
 | 
			
		||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
 | 
			
		||||
 | 
			
		||||
### aliasing constructor
 | 
			
		||||
```
 | 
			
		||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r, element_type * p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: constructs a `local_shared_ptr` that shares ownership with `r` and stores `p`.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `get() == p && local_use_count() == r.local_use_count()`.
 | 
			
		||||
 | 
			
		||||
### aliasing move constructor
 | 
			
		||||
```
 | 
			
		||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> && r, element_type * p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Move-constructs a `local_shared_ptr` from `r`, while storing `p` instead.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `get() == p` and `local_use_count()` equals the old count of `r`. `r` is empty and `r.get() == 0`.
 | 
			
		||||
 | 
			
		||||
### unique_ptr constructor
 | 
			
		||||
```
 | 
			
		||||
template<class Y, class D> local_shared_ptr(std::unique_ptr<Y, D> && r);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: `Y*` should be convertible to `T*`.
 | 
			
		||||
 | 
			
		||||
Effects::
 | 
			
		||||
- When `r.get() == 0`, equivalent to `local_shared_ptr()`;
 | 
			
		||||
- Otherwise, constructs a `local_shared_ptr` that owns `shared_ptr<T>( std::move(r) )`.
 | 
			
		||||
 | 
			
		||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
 | 
			
		||||
 | 
			
		||||
Exception safety:: If an exception is thrown, the constructor has no effect.
 | 
			
		||||
 | 
			
		||||
### destructor
 | 
			
		||||
```
 | 
			
		||||
~local_shared_ptr() noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects::
 | 
			
		||||
- If `*this` is empty, or shares ownership with another `local_shared_ptr` instance (`local_use_count() > 1`), there are no side effects.
 | 
			
		||||
- Otherwise, destroys the owned `shared_ptr`.
 | 
			
		||||
 | 
			
		||||
### assignment
 | 
			
		||||
```
 | 
			
		||||
local_shared_ptr & operator=(local_shared_ptr const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr(r).swap(*this)`.
 | 
			
		||||
Returns:: `*this`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
local_shared_ptr & operator=(local_shared_ptr && r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> && r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y, class D> local_shared_ptr & operator=(std::unique_ptr<Y, D> && r);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr(std::move(r)).swap(*this)`.
 | 
			
		||||
Returns:: `*this`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
local_shared_ptr & operator=(std::nullptr_t) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr().swap(*this)`.
 | 
			
		||||
Returns:: `*this`.
 | 
			
		||||
 | 
			
		||||
### reset
 | 
			
		||||
```
 | 
			
		||||
void reset() noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr().swap(*this)`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Y> void reset(Y * p);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr(p).swap(*this)`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Y, class D> void reset(Y * p, D d);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr(p, d).swap(*this)`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Y, class D, class A> void reset(Y * p, D d, A a);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr(p, d, a).swap(*this)`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Y> void reset(local_shared_ptr<Y> const & r, element_type * p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr(r, p).swap(*this)`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`.
 | 
			
		||||
 | 
			
		||||
### indirection
 | 
			
		||||
```
 | 
			
		||||
T & operator*() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: `T` should not be an array type.
 | 
			
		||||
Returns:: `*get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
T * operator->() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: `T` should not be an array type.
 | 
			
		||||
Returns:: `get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
element_type & operator[](std::ptrdiff_t i) const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: `T` should be an array type. The stored pointer must not be 0. `i >= 0`. If `T` is `U[N]`, `i < N`.
 | 
			
		||||
Returns:: `get()[i]`.
 | 
			
		||||
 | 
			
		||||
### get
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
element_type * get() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: The stored pointer.
 | 
			
		||||
 | 
			
		||||
### local_use_count
 | 
			
		||||
```
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
### conversions
 | 
			
		||||
```
 | 
			
		||||
explicit operator bool() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `get() != 0`.
 | 
			
		||||
 | 
			
		||||
NOTE: On C++03 compilers, the return value is of an unspecified type.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Y> operator shared_ptr<Y>() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> operator weak_ptr<Y>() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: `T*` should be convertible to `Y*`.
 | 
			
		||||
Returns:: a copy of the owned `shared_ptr`.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
```
 | 
			
		||||
void swap(local_shared_ptr & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
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;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: See the description of `operator<`.
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
### comparison
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator==(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator==(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator==(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `a.get() == b.get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator!=(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator!=(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator!=(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `a.get() != b.get()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> bool operator==(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T> bool operator==(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `p.get() == 0`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> bool operator!=(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T> bool operator!=(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `p.get() != 0`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: An unspecified value such that
 | 
			
		||||
  - `operator<` is a strict weak ordering as described in section [lib.alg.sorting] of the {cpp} standard;
 | 
			
		||||
  - under the equivalence relation defined by `operator<`, `!(a < b) && !(b < a)`, two `local_shared_ptr` instances
 | 
			
		||||
    are equivalent if and only if they share ownership or are both empty.
 | 
			
		||||
 | 
			
		||||
NOTE: Allows `local_shared_ptr` objects to be used as keys in associative containers.
 | 
			
		||||
 | 
			
		||||
NOTE: The rest of the comparison operators are omitted by design.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
```
 | 
			
		||||
template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `a.swap(b)`.
 | 
			
		||||
 | 
			
		||||
### get_pointer
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  typename local_shared_ptr<T>::element_type *
 | 
			
		||||
    get_pointer(local_shared_ptr<T> const & p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `p.get()`.
 | 
			
		||||
 | 
			
		||||
NOTE: Provided as an aid to generic programming. Used by `mem_fn`.
 | 
			
		||||
 | 
			
		||||
### static_pointer_cast
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  local_shared_ptr<T> static_pointer_cast(local_shared_ptr<U> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: The expression `static_cast<T*>( (U*)0 )` must be well-formed.
 | 
			
		||||
Returns:: `local_shared_ptr<T>( r, static_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.
 | 
			
		||||
 | 
			
		||||
CAUTION: The seemingly equivalent expression `local_shared_ptr<T>(static_cast<T*>(r.get()))` will eventually
 | 
			
		||||
result in undefined behavior, attempting to delete the same object twice.
 | 
			
		||||
 | 
			
		||||
### const_pointer_cast
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  local_shared_ptr<T> const_pointer_cast(local_shared_ptr<U> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: The expression `const_cast<T*>( (U*)0 )` must be well-formed.
 | 
			
		||||
Returns:: `local_shared_ptr<T>( r, const_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.
 | 
			
		||||
 | 
			
		||||
### dynamic_pointer_cast
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
    local_shared_ptr<T> dynamic_pointer_cast(local_shared_ptr<U> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: The expression `dynamic_cast<T*>( (U*)0 )` must be well-formed.
 | 
			
		||||
Returns::
 | 
			
		||||
  - When `dynamic_cast<typename local_shared_ptr<T>::element_type*>(r.get())` returns a nonzero value `p`, `local_shared_ptr<T>(r, p)`;
 | 
			
		||||
  - Otherwise, `local_shared_ptr<T>()`.
 | 
			
		||||
 | 
			
		||||
### reinterpret_pointer_cast
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  local_shared_ptr<T> reinterpret_pointer_cast(local_shared_ptr<U> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Requires:: The expression `reinterpret_cast<T*>( (U*)0 )` must be well-formed.
 | 
			
		||||
Returns:: `local_shared_ptr<T>( r, reinterpret_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.
 | 
			
		||||
 | 
			
		||||
### operator<<
 | 
			
		||||
```
 | 
			
		||||
template<class E, class T, class Y>
 | 
			
		||||
  std::basic_ostream<E, T> &
 | 
			
		||||
    operator<< (std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p);
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: `os << p.get();`.
 | 
			
		||||
Returns:: `os`.
 | 
			
		||||
 | 
			
		||||
### get_deleter
 | 
			
		||||
```
 | 
			
		||||
template<class D, class T>
 | 
			
		||||
  D * get_deleter(local_shared_ptr<T> const & p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: If `*this` owns a `shared_ptr` instance `p`, `get_deleter<D>( p )`, otherwise 0.
 | 
			
		||||
 | 
			
		||||
@@ -1,81 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#make_local_shared]
 | 
			
		||||
# make_local_shared: Creating local_shared_ptr
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: make_local_shared_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The function templates `make_local_shared` and `allocate_local_shared` provide
 | 
			
		||||
convenient, safe and efficient ways to create `local_shared_ptr` objects. They
 | 
			
		||||
are analogous to `make_shared` and `allocate_shared` for `shared_ptr`.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`make_local_shared` and `allocate_local_shared` are defined in
 | 
			
		||||
`<boost/smart_ptr/make_local_shared.hpp>`.
 | 
			
		||||
 | 
			
		||||
[subs=+quotes]
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
  `// only if T is not an array type`
 | 
			
		||||
  template<class T, class... Args>
 | 
			
		||||
    local_shared_ptr<T> make_local_shared(Args&&... args);
 | 
			
		||||
  template<class T, class A, class... Args>
 | 
			
		||||
    local_shared_ptr<T> allocate_local_shared(const A& a, Args&&... args);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    local_shared_ptr<T> make_local_shared(std::size_t n);
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[N]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    local_shared_ptr<T> make_local_shared();
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    local_shared_ptr<T> allocate_local_shared(const A& a);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    local_shared_ptr<T> make_local_shared(std::size_t n,
 | 
			
		||||
      const remove_extent_t<T>& v);
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n,
 | 
			
		||||
      const remove_extent_t<T>& v);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[N]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    local_shared_ptr<T> make_local_shared(const remove_extent_t<T>& v);
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    local_shared_ptr<T> allocate_local_shared(const A& a,
 | 
			
		||||
      const remove_extent_t<T>& v);
 | 
			
		||||
 | 
			
		||||
  `// only if T is not an array type of the form U[]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    local_shared_ptr<T> make_local_shared_noinit();
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    local_shared_ptr<T> allocate_local_shared_noinit(const A& a);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[N]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    local_shared_ptr<T> make_local_shared_noinit(std::size_t n);
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    local_shared_ptr<T> allocate_local_shared_noinit(const A& a,
 | 
			
		||||
      std::size_t n);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The requirements and effects of these functions are the same as `make_shared`
 | 
			
		||||
and `allocate_shared`, except that a `local_shared_ptr` is returned.
 | 
			
		||||
@@ -1,295 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
Copyright 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#make_shared]
 | 
			
		||||
# make_shared: Creating shared_ptr
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: make_shared_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The function templates `make_shared` and `allocate_shared` provide convenient,
 | 
			
		||||
safe and efficient ways to create `shared_ptr` objects.
 | 
			
		||||
 | 
			
		||||
## Rationale
 | 
			
		||||
 | 
			
		||||
Consistent use of `shared_ptr` can eliminate the need to use an explicit
 | 
			
		||||
`delete`, but alone it provides no support in avoiding explicit `new`. There
 | 
			
		||||
were repeated requests from users for a factory function that creates an
 | 
			
		||||
object of a given type and returns a `shared_ptr` to it. Besides convenience
 | 
			
		||||
and style, such a function is also exception safe and considerably faster
 | 
			
		||||
because it can use a single allocation for both the object and its
 | 
			
		||||
corresponding control block, eliminating a significant portion of
 | 
			
		||||
`shared_ptr` construction overhead. This eliminates one of the major
 | 
			
		||||
efficiency complaints about `shared_ptr`.
 | 
			
		||||
 | 
			
		||||
The family of overloaded function templates, `make_shared` and
 | 
			
		||||
`allocate_shared`, were provided to address this need. `make_shared` uses the
 | 
			
		||||
global `operator new` to allocate memory, whereas `allocate_shared` uses an
 | 
			
		||||
user-supplied allocator, allowing finer control.
 | 
			
		||||
 | 
			
		||||
The rationale for choosing the name `make_shared` is that the expression
 | 
			
		||||
`make_shared<Widget>()` can be read aloud and conveys the intended meaning.
 | 
			
		||||
 | 
			
		||||
Originally the Boost function templates `allocate_shared` and `make_shared`
 | 
			
		||||
were provided for scalar objects only. There was a need to have efficient
 | 
			
		||||
allocation of array objects. One criticism of class template `shared_array`
 | 
			
		||||
was always the lack of a utility like `make_shared` that uses only a single
 | 
			
		||||
allocation. When `shared_ptr` was enhanced to support array types, additional
 | 
			
		||||
overloads of `allocate_shared` and `make_shared` were provided for array
 | 
			
		||||
types.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`make_shared` and `allocate_shared` are defined in
 | 
			
		||||
`<boost/smart_ptr/make_shared.hpp>`.
 | 
			
		||||
 | 
			
		||||
[subs=+quotes]
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
  `// only if T is not an array type`
 | 
			
		||||
  template<class T, class... Args>
 | 
			
		||||
    shared_ptr<T> make_shared(Args&&... args);
 | 
			
		||||
  template<class T, class A, class... Args>
 | 
			
		||||
    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    shared_ptr<T> make_shared(std::size_t n);
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    shared_ptr<T> allocate_shared(const A& a, std::size_t n);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[N]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    shared_ptr<T> make_shared();
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    shared_ptr<T> allocate_shared(const A& a);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[]`
 | 
			
		||||
  template<class T> shared_ptr<T>
 | 
			
		||||
    make_shared(std::size_t n, const remove_extent_t<T>& v);
 | 
			
		||||
  template<class T, class A> shared_ptr<T>
 | 
			
		||||
    allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[N]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    shared_ptr<T> make_shared(const remove_extent_t<T>& v);
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
 | 
			
		||||
 | 
			
		||||
  `// only if T is not an array type of the form U[]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    shared_ptr<T> make_shared_noinit();
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    shared_ptr<T> allocate_shared_noinit(const A& a);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[N]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    shared_ptr<T> make_shared_noinit(std::size_t n);
 | 
			
		||||
  template<class T, class A>
 | 
			
		||||
    shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Common Requirements
 | 
			
		||||
 | 
			
		||||
The common requirements that apply to all `make_shared` and `allocate_shared`
 | 
			
		||||
overloads, unless specified otherwise, are described below.
 | 
			
		||||
 | 
			
		||||
Requires:: `A` shall be an _allocator_. The copy constructor and destructor
 | 
			
		||||
of `A` shall not throw exceptions.
 | 
			
		||||
 | 
			
		||||
Effects:: Allocates memory for an object of type `T`  or `n` objects of `U`
 | 
			
		||||
(if `T` is an array type of the form `U[]` and  `n` is determined by
 | 
			
		||||
arguments, as specified by the concrete overload). The object is initialized
 | 
			
		||||
from arguments as specified by the concrete overload. Uses a rebound copy of
 | 
			
		||||
`a` (for an unspecified `value_type`) to allocate memory. If an exception is
 | 
			
		||||
thrown, the functions have no effect.
 | 
			
		||||
 | 
			
		||||
Returns:: A `shared_ptr` instance that stores and owns the address of the
 | 
			
		||||
newly constructed object.
 | 
			
		||||
 | 
			
		||||
Postconditions:: `r.get() != 0` and `r.use_count() == 1`, where `r`
 | 
			
		||||
is the return value.
 | 
			
		||||
 | 
			
		||||
Throws:: `std::bad_alloc`, an exception thrown from `A::allocate`, or from the
 | 
			
		||||
initialization of the object.
 | 
			
		||||
 | 
			
		||||
Remarks::
 | 
			
		||||
* Performs no more than one memory allocation. This provides efficiency
 | 
			
		||||
equivalent to an intrusive smart pointer.
 | 
			
		||||
* When an object of an array type is specified to be initialized to a value of
 | 
			
		||||
the same type `v`, this shall be interpreted to mean that each array element
 | 
			
		||||
of the object is initialized to the corresponding element from `v`.
 | 
			
		||||
* When an object of an array type is specified to be value-initialized, this
 | 
			
		||||
shall be interpreted to mean that each array element of the object is
 | 
			
		||||
value-initialized.
 | 
			
		||||
* When a (sub)object of non-array type `U` is specified to be initialized to
 | 
			
		||||
a value `v`, or constructed from `args\...`, `make_shared` shall perform
 | 
			
		||||
this initialization via the expression `::new(p) U(expr)` (where
 | 
			
		||||
`_expr_` is `v` or `std::forward<Args>(args)\...)` respectively) and `p`
 | 
			
		||||
has type `void*` and points to storage suitable to hold an object of type
 | 
			
		||||
`U`.
 | 
			
		||||
* When a (sub)object of non-array type `U` is specified to be initialized to
 | 
			
		||||
a value `v`, or constructed from `args\...`, `allocate_shared` shall
 | 
			
		||||
perform this initialization via the expression
 | 
			
		||||
`std::allocator_traits<A2>::construct(a2, p, expr)` (where
 | 
			
		||||
`_expr_` is `v` or `std::forward<Args>(args)\...)` respectively), `p`
 | 
			
		||||
points to storage suitable to hold an object of type `U`, and `a2` of
 | 
			
		||||
type `A2` is a rebound copy `a` such that its `value_type` is `U`.
 | 
			
		||||
* When a (sub)object of non-array type `U` is specified to be
 | 
			
		||||
default-initialized, `make_shared_noinit` and `allocate_shared_noinit` shall
 | 
			
		||||
perform this initialization via the expression `::new(p) U`, where
 | 
			
		||||
`p` has type `void*` and points to storage suitable to hold an object of
 | 
			
		||||
type `U`.
 | 
			
		||||
* When a (sub)object of non-array type `U` is specified to be
 | 
			
		||||
value-initialized, `make_shared` shall perform this initialization via the
 | 
			
		||||
expression `::new(p) U()`, where `p` has type `void*` and points to
 | 
			
		||||
storage suitable to hold an object of type `U`.
 | 
			
		||||
* When a (sub)object of non-array type `U` is specified to be
 | 
			
		||||
value-initialized, `allocate_shared` shall perform this initialization via the
 | 
			
		||||
expression `std::allocator_traits<A2>::construct(a2, p)`, where
 | 
			
		||||
`p` points to storage suitable to hold an object of type `U` and `a2` of
 | 
			
		||||
type `A2` is a rebound copy of `a` such that its value_type is `U`.
 | 
			
		||||
* Array elements are initialized in ascending order of their addresses.
 | 
			
		||||
* When the lifetime of the object managed by the return value ends, or when
 | 
			
		||||
the initialization of an array element throws an exception, the initialized
 | 
			
		||||
elements should be destroyed in the reverse order of their construction.
 | 
			
		||||
 | 
			
		||||
NOTE: These functions will typically allocate more memory than the total size
 | 
			
		||||
of the element objects to allow for internal bookkeeping structures such as
 | 
			
		||||
the reference counts.
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class... Args>
 | 
			
		||||
  shared_ptr<T> make_shared(Args&&... args);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
```
 | 
			
		||||
template<class T, class A, class... Args>
 | 
			
		||||
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is not an array type.
 | 
			
		||||
Returns::: A `shared_ptr` to an object of type `T`, constructed from
 | 
			
		||||
`args\...`.
 | 
			
		||||
Examples:::
 | 
			
		||||
* `auto p = make_shared<int>();`
 | 
			
		||||
* `auto p = make_shared<std::vector<int> >(16, 1);`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  shared_ptr<T> make_shared(std::size_t n);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
```
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
  shared_ptr<T> allocate_shared(const A& a, std::size_t n);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is an array type of the form `U[]`.
 | 
			
		||||
Returns::: A `shared_ptr` to a sequence of `n` value-initialized objects of
 | 
			
		||||
type `U`.
 | 
			
		||||
Examples:::
 | 
			
		||||
* `auto p = make_shared<double[]>(1024);`
 | 
			
		||||
* `auto p = make_shared<double[][2][2]>(6);`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  shared_ptr<T> make_shared();
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
```
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
  shared_ptr<T> allocate_shared(const A& a);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is an array type of the form `U[N]`.
 | 
			
		||||
Returns::: A `shared_ptr` to a sequence of `N` value-initialized objects of
 | 
			
		||||
type `U`.
 | 
			
		||||
Examples:::
 | 
			
		||||
* `auto p = make_shared<double[1024]>();`
 | 
			
		||||
* `auto p = make_shared<double[6][2][2]>();`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> shared_ptr<T>
 | 
			
		||||
  make_shared(std::size_t n, const remove_extent_t<T>& v);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
```
 | 
			
		||||
template<class T, class A> shared_ptr<T>
 | 
			
		||||
  allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is an array type of the form `U[]`.
 | 
			
		||||
Returns::: A `shared_ptr` to a sequence of `n` objects of type `U`, each
 | 
			
		||||
initialized to `v`.
 | 
			
		||||
Examples:::
 | 
			
		||||
* `auto p = make_shared<double[]>(1024, 1.0);`
 | 
			
		||||
* `auto p = make_shared<double[][2]>(6, {1.0, 0.0});`
 | 
			
		||||
* `auto p = make_shared<std::vector<int>[]>(4, {1, 2});`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  shared_ptr<T> make_shared(const remove_extent_t<T>& v);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
```
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
  shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is an array type of the form `U[N]`.
 | 
			
		||||
Returns::: A `shared_ptr` to a sequence of `N` objects of type `U`, each
 | 
			
		||||
initialized to `v`.
 | 
			
		||||
Examples:::
 | 
			
		||||
* `auto p = make_shared<double[1024]>(1.0);`
 | 
			
		||||
* `auto p = make_shared<double[6][2]>({1.0, 0.0});`
 | 
			
		||||
* `auto p = make_shared<std::vector<int>[4]>({1, 2});`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  shared_ptr<T> make_shared_noinit();
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
```
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
  shared_ptr<T> allocate_shared_noinit(const A& a);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is not an array type, or an array type of the `U[N]`.
 | 
			
		||||
Returns::: A `shared_ptr` to a default-initialized object of type `T`, or a
 | 
			
		||||
sequence of `N` default-initialized objects of type `U`, respectively.
 | 
			
		||||
Example::: `auto p = make_shared_noinit<double[1024]>();`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  shared_ptr<T> make_shared_noinit(std::size_t n);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
```
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
  shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is an array type of the form `U[]`.
 | 
			
		||||
Returns::: A `shared_ptr` to a sequence of `_n_` default-initialized objects
 | 
			
		||||
of type `U`.
 | 
			
		||||
Example::: `auto p = make_shared_noinit<double[]>(1024);`
 | 
			
		||||
@@ -1,115 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
Copyright 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#make_unique]
 | 
			
		||||
# make_unique: Creating unique_ptr
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: make_unique_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The `make_unique` function templates provide convenient and safe ways to
 | 
			
		||||
create `std::unique_ptr` objects.
 | 
			
		||||
 | 
			
		||||
## Rationale
 | 
			
		||||
 | 
			
		||||
The {cpp}11 standard introduced `std::unique_ptr` but did not provide any
 | 
			
		||||
`make_unique` utility like `std::make_shared` that provided the same
 | 
			
		||||
exception safety and facility to avoid writing `new` expressions. Before it
 | 
			
		||||
was implemented by some standard library vendors (and prior to the {cpp}14
 | 
			
		||||
standard introducing `std::make_unique`), this library provided it due to
 | 
			
		||||
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`.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`make_unique` is defined in `<boost/smart_ptr/make_unique.hpp>`.
 | 
			
		||||
 | 
			
		||||
[subs=+quotes]
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
  `// only if T is not an array type`
 | 
			
		||||
  template<class T, class... Args>
 | 
			
		||||
    std::unique_ptr<T> make_unique(Args&&... args);
 | 
			
		||||
 | 
			
		||||
  `// only if T is not an array type`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    std::unique_ptr<T> make_unique(std::size_t n);
 | 
			
		||||
 | 
			
		||||
  `// only if T is not an array type`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    std::unique_ptr<T> make_unique_noinit();
 | 
			
		||||
 | 
			
		||||
  `// only if T is an array type of the form U[]`
 | 
			
		||||
  template<class T>
 | 
			
		||||
    std::unique_ptr<T> make_unique_noinit(std::size_t n);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class... Args>
 | 
			
		||||
  std::unique_ptr<T> make_unique(Args&&... args);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is not an array type.
 | 
			
		||||
Returns::: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`.
 | 
			
		||||
Example::: `auto p = make_unique<int>();`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is not an array type.
 | 
			
		||||
Returns::: `std::unique_ptr<T>(new T(std::move(v))`.
 | 
			
		||||
Example::: `auto p = make_unique<std::vector<int> >({1, 2});`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  std::unique_ptr<T> make_unique(std::size_t n);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is an array type of the form `U[]`.
 | 
			
		||||
Returns::: `std::unique_ptr<U[]>(new U[n]())`.
 | 
			
		||||
Example::: `auto p = make_unique<double[]>(1024);`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  std::unique_ptr<T> make_unique_noinit();
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is not an array type.
 | 
			
		||||
Returns::: `std::unique_ptr<T>(new T)`.
 | 
			
		||||
Example::: `auto p = make_unique_noinit<double[1024]>();`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  std::unique_ptr<T> make_unique_noinit(std::size_t n);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Remarks::: These overloads shall only participate in overload resolution when
 | 
			
		||||
`T` is an array type of the form `U[]`.
 | 
			
		||||
Returns::: `std::unique_ptr<U[]>(new U[n])`.
 | 
			
		||||
Example::: `auto p = make_unique_noinit<double[]>(1024);`
 | 
			
		||||
@@ -1,213 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#pointer_cast]
 | 
			
		||||
# Generic Pointer Casts
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: pointer_cast_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The pointer cast function templates (`static_pointer_cast`,
 | 
			
		||||
`dynamic_pointer_cast`, `const_pointer_cast`, and `reinterpret_pointer_cast`)
 | 
			
		||||
provide a way to write generic pointer castings for raw pointers,
 | 
			
		||||
`std::shared_ptr` and `std::unique_ptr`.
 | 
			
		||||
 | 
			
		||||
There is test and example code in
 | 
			
		||||
link:../../test/pointer_cast_test.cpp[pointer_cast_test.cpp]
 | 
			
		||||
 | 
			
		||||
## Rationale
 | 
			
		||||
 | 
			
		||||
Boost smart pointers usually overload those functions to provide a mechanism
 | 
			
		||||
to emulate pointers casts. For example, `shared_ptr<T>` implements a static
 | 
			
		||||
pointer cast this way:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  shared_ptr<T> static_pointer_cast(const shared_ptr<U>& p);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Pointer cast functions templates are overloads of `static_pointer_cast`,
 | 
			
		||||
`dynamic_pointer_cast`, `const_pointer_cast`, and `reinterpret_pointer_cast`
 | 
			
		||||
for raw pointers, `std::shared_ptr` and `std::unique_ptr`. This way when
 | 
			
		||||
developing pointer type independent classes, for example, memory managers or
 | 
			
		||||
shared memory compatible classes, the same code can be used for raw and smart
 | 
			
		||||
pointers.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
The generic pointer casts are defined in `<boost/pointer_cast.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template<class T, class U> T* static_pointer_cast(U* p) noexcept;
 | 
			
		||||
  template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept;
 | 
			
		||||
  template<class T, class U> T* const_pointer_cast(U* p) noexcept;
 | 
			
		||||
  template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U> std::shared_ptr<T>
 | 
			
		||||
    static_pointer_cast(const std::shared_ptr<U>& p) noexcept;
 | 
			
		||||
  template<class T, class U> std::shared_ptr<T>
 | 
			
		||||
    dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept;
 | 
			
		||||
  template<class T, class U> std::shared_ptr<T>
 | 
			
		||||
    const_pointer_cast(const std::shared_ptr<U>& p) noexcept;
 | 
			
		||||
  template<class T, class U> std::shared_ptr<T>
 | 
			
		||||
    reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U> std::unique_ptr<T>
 | 
			
		||||
    static_pointer_cast(std::unique_ptr<U>&& p) noexcept;
 | 
			
		||||
  template<class T, class U> std::unique_ptr<T>
 | 
			
		||||
    dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept;
 | 
			
		||||
  template<class T, class U> std::unique_ptr<T>
 | 
			
		||||
    const_pointer_cast(std::unique_ptr<U>&& p) noexcept;
 | 
			
		||||
  template<class T, class U> std::unique_ptr<T>
 | 
			
		||||
    reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
### static_pointer_cast
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> T* static_pointer_cast(U* p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `static_cast<T*>(p)`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> std::shared_ptr<T>
 | 
			
		||||
  static_pointer_cast(const std::shared_ptr<U>& p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `std::static_pointer_cast<T>(p)`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> std::unique_ptr<T>
 | 
			
		||||
  static_pointer_cast(std::unique_ptr<U>&& p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Requires::: The expression `static_cast<T*>((U*)0)` must be well-formed.
 | 
			
		||||
Returns::: `std::unique_ptr<T>(static_cast<typename
 | 
			
		||||
std::unique_ptr<T>::element_type*>(p.release()))`.
 | 
			
		||||
 | 
			
		||||
CAUTION: The seemingly equivalent expression
 | 
			
		||||
`std::unique_ptr<T>(static_cast<T*>(p.get()))` will eventually result in
 | 
			
		||||
undefined behavior, attempting to delete the same object twice.
 | 
			
		||||
 | 
			
		||||
### dynamic_pointer_cast
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `dynamic_cast<T*>(p)`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> std::shared_ptr<T>
 | 
			
		||||
  dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `std::dynamic_pointer_cast<T>(p)`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> std::unique_ptr<T>
 | 
			
		||||
  dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Requires:::
 | 
			
		||||
* The expression `static_cast<T*>((U*)0)` must be well-formed.
 | 
			
		||||
* `T` must have a virtual destructor.
 | 
			
		||||
Returns:::
 | 
			
		||||
* When `dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.get())`
 | 
			
		||||
returns a non-zero value, `std::unique_ptr<T>(dynamic_cast<typename
 | 
			
		||||
std::unique_ptr<T>::element_type*>(p.release()));`.
 | 
			
		||||
* Otherwise, `std::unique_ptr<T>()`.
 | 
			
		||||
 | 
			
		||||
### const_pointer_cast
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> T* const_pointer_cast(U* p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `const_cast<T*>(p)`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> std::shared_ptr<T>
 | 
			
		||||
  const_pointer_cast(const std::shared_ptr<U>& p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `std::const_pointer_cast<T>(p)`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> std::unique_ptr<T>
 | 
			
		||||
  const_pointer_cast(std::unique_ptr<U>&& p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Requires::: The expression `const_cast<T*>((U*)0)` must be well-formed.
 | 
			
		||||
Returns::: `std::unique_ptr<T>(const_cast<typename
 | 
			
		||||
std::unique_ptr<T>::element_type*>(p.release()))`.
 | 
			
		||||
 | 
			
		||||
### reinterpret_pointer_cast
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `reinterpret_cast<T*>(p)`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> std::shared_ptr<T>
 | 
			
		||||
  reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `std::reinterpret_pointer_cast<T>(p)`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U> std::unique_ptr<T>
 | 
			
		||||
  reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Requires::: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed.
 | 
			
		||||
Returns::: `std::unique_ptr<T>(reinterpret_cast<typename
 | 
			
		||||
std::unique_ptr<T>::element_type*>(p.release()))`.
 | 
			
		||||
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
The following example demonstrates how the generic pointer casts help us
 | 
			
		||||
create pointer independent code.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
#include <boost/pointer_cast.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
class base {
 | 
			
		||||
public:
 | 
			
		||||
  virtual ~base() { }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class derived : public base { };
 | 
			
		||||
 | 
			
		||||
template<class Ptr>
 | 
			
		||||
void check_if_it_is_derived(const Ptr& ptr)
 | 
			
		||||
{
 | 
			
		||||
  assert(boost::dynamic_pointer_cast<derived>(ptr) != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  base* ptr = new derived;
 | 
			
		||||
  boost::shared_ptr<base> sptr(new derived);
 | 
			
		||||
 | 
			
		||||
  check_if_it_is_derived(ptr);
 | 
			
		||||
  check_if_it_is_derived(sptr);
 | 
			
		||||
 | 
			
		||||
  delete ptr;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
@@ -1,114 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2005, 2006 Ion Gaztañaga
 | 
			
		||||
Copyright 2005, 2006, 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#pointer_to_other]
 | 
			
		||||
# pointer_to_other
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: pointer_to_other_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The `pointer_to_other` utility provides a way, given a source pointer type, to obtain a pointer of the same type
 | 
			
		||||
to another pointee type.
 | 
			
		||||
 | 
			
		||||
There is test/example code in link:../../test/pointer_to_other_test.cpp[pointer_to_other_test.cpp].
 | 
			
		||||
 | 
			
		||||
## Rationale
 | 
			
		||||
 | 
			
		||||
When building pointer independent classes, like memory managers, allocators, or containers, there is often a need to
 | 
			
		||||
define pointers generically, so that if a template parameter represents a pointer (for example, a raw or smart pointer
 | 
			
		||||
to an `int`), we can define another pointer of the same type to another pointee (a raw or smart pointer to a `float`.)
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template <class IntPtr> class FloatPointerHolder
 | 
			
		||||
{
 | 
			
		||||
    // Let's define a pointer to a float
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::pointer_to_other
 | 
			
		||||
        <IntPtr, float>::type float_ptr_t;
 | 
			
		||||
 | 
			
		||||
    float_ptr_t float_ptr;
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`pointer_to_other` is defined in `<boost/smart_ptr/pointer_to_other.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T, class U> struct pointer_to_other;
 | 
			
		||||
 | 
			
		||||
  template<class T, class U,
 | 
			
		||||
    template <class> class Sp>
 | 
			
		||||
      struct pointer_to_other< Sp<T>, U >
 | 
			
		||||
  {
 | 
			
		||||
    typedef Sp<U> type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class T, class T2, class U,
 | 
			
		||||
    template <class, class> class Sp>
 | 
			
		||||
      struct pointer_to_other< Sp<T, T2>, U >
 | 
			
		||||
  {
 | 
			
		||||
    typedef Sp<U, T2> type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class T, class T2, class T3, class U,
 | 
			
		||||
    template <class, class, class> class Sp>
 | 
			
		||||
      struct pointer_to_other< Sp<T, T2, T3>, U >
 | 
			
		||||
  {
 | 
			
		||||
    typedef Sp<U, T2, T3> type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    struct pointer_to_other< T*, U > 
 | 
			
		||||
  {
 | 
			
		||||
    typedef U* type;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If these definitions are not correct for a specific smart pointer, we can define a specialization of `pointer_to_other`.
 | 
			
		||||
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
// Let's define a memory allocator that can
 | 
			
		||||
// work with raw and smart pointers
 | 
			
		||||
 | 
			
		||||
#include <boost/pointer_to_other.hpp>
 | 
			
		||||
 | 
			
		||||
template <class VoidPtr>
 | 
			
		||||
class memory_allocator
 | 
			
		||||
{
 | 
			
		||||
    // Predefine a memory_block
 | 
			
		||||
 | 
			
		||||
    struct block;
 | 
			
		||||
 | 
			
		||||
    // Define a pointer to a memory_block from a void pointer
 | 
			
		||||
    // If VoidPtr is void *, block_ptr_t is block*
 | 
			
		||||
    // If VoidPtr is smart_ptr<void>, block_ptr_t is smart_ptr<block>
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::pointer_to_other
 | 
			
		||||
        <VoidPtr, block>::type block_ptr_t;
 | 
			
		||||
 | 
			
		||||
    struct block
 | 
			
		||||
    {
 | 
			
		||||
        std::size_t size;
 | 
			
		||||
        block_ptr_t next_block;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    block_ptr_t free_blocks;
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
As we can see, using `pointer_to_other` we can create pointer independent code.
 | 
			
		||||
@@ -1,175 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 1999 Greg Colvin and Beman Dawes
 | 
			
		||||
Copyright 2002 Darin Adler
 | 
			
		||||
Copyright 2002-2005, 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#scoped_array]
 | 
			
		||||
# scoped_array: Scoped Array Ownership
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: scoped_array_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The `scoped_array` class template stores a pointer to a dynamically allocated array.
 | 
			
		||||
(Dynamically allocated arrays are allocated with the {cpp} `new[]` expression.) The array
 | 
			
		||||
pointed to is guaranteed to be deleted, either on destruction of the `scoped_array`,
 | 
			
		||||
or via an explicit `reset`.
 | 
			
		||||
 | 
			
		||||
The `scoped_array` template is a simple solution for simple needs. It supplies a basic
 | 
			
		||||
"resource acquisition is initialization" facility, without shared-ownership or
 | 
			
		||||
transfer-of-ownership semantics. Both its name and enforcement of semantics
 | 
			
		||||
(by being  noncopyable) signal its intent to retain ownership solely within the current scope.
 | 
			
		||||
Because it is noncopyable, it is safer than `shared_ptr<T[]>` for pointers which should not be copied.
 | 
			
		||||
 | 
			
		||||
Because `scoped_array` is so simple, in its usual implementation every operation is as fast as a
 | 
			
		||||
built-in array pointer and it has no more space overhead that a built-in array pointer.
 | 
			
		||||
 | 
			
		||||
It cannot be used in {cpp} standard library containers. See `shared_ptr<T[]>` if `scoped_array`
 | 
			
		||||
does not meet your needs.
 | 
			
		||||
 | 
			
		||||
It cannot correctly hold a pointer to a single object. See `scoped_ptr` for that usage.
 | 
			
		||||
 | 
			
		||||
`std::vector` is an alternative to `scoped_array` that is a bit heavier duty but far more flexible.
 | 
			
		||||
`boost::array` is an alternative that does not use dynamic allocation.
 | 
			
		||||
 | 
			
		||||
The class template is parameterized on `T`, the type of the object pointed to.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`scoped_array` is defined in `<boost/smart_ptr/scoped_array.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class scoped_array {
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    scoped_array(scoped_array const &);
 | 
			
		||||
    scoped_array & operator=(scoped_array const &);
 | 
			
		||||
 | 
			
		||||
    void operator==( scoped_array const& ) const;
 | 
			
		||||
    void operator!=( scoped_array const& ) const;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit scoped_array(T * p = 0) noexcept;
 | 
			
		||||
    ~scoped_array() noexcept;
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) noexcept;
 | 
			
		||||
 | 
			
		||||
    T & operator[](std::ptrdiff_t i) const noexcept;
 | 
			
		||||
    T * get() const noexcept;
 | 
			
		||||
 | 
			
		||||
    explicit operator bool () const noexcept;
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_array & b) noexcept;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator==( scoped_array<T> const & p, std::nullptr_t ) noexcept;
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator==( std::nullptr_t, scoped_array<T> const & p ) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator!=( scoped_array<T> const & p, std::nullptr_t ) noexcept;
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator!=( std::nullptr_t, scoped_array<T> const & p ) noexcept;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
### element_type
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
Provides the type of the stored pointer.
 | 
			
		||||
 | 
			
		||||
### constructors
 | 
			
		||||
 | 
			
		||||
    explicit scoped_array(T * p = 0) noexcept;
 | 
			
		||||
 | 
			
		||||
Constructs a `scoped_array`, storing a copy of `p`, which must have been
 | 
			
		||||
allocated via a {cpp} `new[]` expression or be 0. `T` is not required be a complete type.
 | 
			
		||||
 | 
			
		||||
### destructor
 | 
			
		||||
 | 
			
		||||
    ~scoped_array() noexcept;
 | 
			
		||||
 | 
			
		||||
Deletes the array pointed to by the stored pointer. Note that `delete[]` on a pointer with
 | 
			
		||||
a value of 0 is harmless. `T` must be complete, and `delete[]` on the stored pointer must
 | 
			
		||||
not throw exceptions.
 | 
			
		||||
 | 
			
		||||
### reset
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) noexcept;
 | 
			
		||||
 | 
			
		||||
Deletes the array pointed to by the stored pointer and then stores a copy of `p`,
 | 
			
		||||
which must have been allocated via a {cpp} `new[]` expression or be 0. `T` must be complete,
 | 
			
		||||
and `delete[]` on the stored pointer must not throw exceptions.
 | 
			
		||||
 | 
			
		||||
### subscripting
 | 
			
		||||
 | 
			
		||||
    T & operator[](std::ptrdiff_t i) const noexcept;
 | 
			
		||||
 | 
			
		||||
Returns a reference to element `i` of the array pointed to by the stored pointer.
 | 
			
		||||
Behavior is undefined and almost certainly undesirable if the stored pointer is 0,
 | 
			
		||||
or if `i` is less than 0 or is greater than or equal to the number of elements in
 | 
			
		||||
the array.
 | 
			
		||||
 | 
			
		||||
### get
 | 
			
		||||
 | 
			
		||||
    T * get() const noexcept;
 | 
			
		||||
 | 
			
		||||
Returns the stored pointer. `T` need not be a complete type.
 | 
			
		||||
 | 
			
		||||
### conversions
 | 
			
		||||
 | 
			
		||||
    explicit operator bool () const noexcept;
 | 
			
		||||
 | 
			
		||||
Returns `get() != 0`.
 | 
			
		||||
 | 
			
		||||
NOTE: On C++03 compilers, the return value is of an unspecified type.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_array & b) noexcept;
 | 
			
		||||
 | 
			
		||||
Exchanges the contents of the two smart pointers. `T` need not be a complete type.
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
 | 
			
		||||
    template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b) noexcept;
 | 
			
		||||
 | 
			
		||||
Equivalent to `a.swap(b)`.
 | 
			
		||||
 | 
			
		||||
### comparisons
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
      bool operator==( scoped_array<T> const & p, std::nullptr_t ) noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
      bool operator==( std::nullptr_t, scoped_array<T> const & p ) noexcept;
 | 
			
		||||
 | 
			
		||||
Returns `p.get() == nullptr`.
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
      bool operator!=( scoped_array<T> const & p, std::nullptr_t ) noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
      bool operator!=( std::nullptr_t, scoped_array<T> const & p ) noexcept;
 | 
			
		||||
 | 
			
		||||
Returns `p.get() != nullptr`.
 | 
			
		||||
@@ -1,234 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#scoped_ptr]
 | 
			
		||||
# scoped_ptr: Scoped Object Ownership
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: scoped_ptr_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The `scoped_ptr` class template stores a pointer to a dynamically allocated object.
 | 
			
		||||
(Dynamically allocated objects are allocated with the {cpp} `new` expression.) The
 | 
			
		||||
object pointed to is guaranteed to be deleted, either on destruction of the `scoped_ptr`,
 | 
			
		||||
or via an explicit `reset`. See the <<scoped_ptr_example,example>>.
 | 
			
		||||
 | 
			
		||||
`scoped_ptr` is a simple solution for simple needs. It supplies a basic "resource acquisition
 | 
			
		||||
is initialization" facility, without shared-ownership or transfer-of-ownership semantics.
 | 
			
		||||
Both its name and enforcement of semantics (by being  noncopyable) signal its intent to retain
 | 
			
		||||
ownership solely within the current scope. Because it is noncopyable, it is safer than `shared_ptr`
 | 
			
		||||
for pointers which should not be copied.
 | 
			
		||||
 | 
			
		||||
Because `scoped_ptr` is simple, in its usual implementation every operation is as fast as for a
 | 
			
		||||
built-in pointer and it has no more space overhead that a built-in pointer.
 | 
			
		||||
 | 
			
		||||
`scoped_ptr` cannot be used in {cpp} Standard Library containers. Use `shared_ptr` or `std::unique_ptr`
 | 
			
		||||
if you need a smart pointer that can.
 | 
			
		||||
 | 
			
		||||
`scoped_ptr` cannot correctly hold a pointer to a dynamically allocated array. See `scoped_array` for that usage.
 | 
			
		||||
 | 
			
		||||
The class template is parameterized on `T`, the type of the object pointed to. Destroying `T` must not thow exceptions,
 | 
			
		||||
and `T` must be complete at the point `scoped_ptr<T>::~scoped_ptr` is instantiated.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`scoped_ptr` is defined in `<boost/smart_ptr/scoped_ptr.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class scoped_ptr {
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    scoped_ptr(scoped_ptr const&);
 | 
			
		||||
    scoped_ptr& operator=(scoped_ptr const&);
 | 
			
		||||
 | 
			
		||||
    void operator==(scoped_ptr const&) const;
 | 
			
		||||
    void operator!=(scoped_ptr const&) const;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit scoped_ptr(T * p = 0) noexcept;
 | 
			
		||||
    ~scoped_ptr() noexcept;
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) noexcept;
 | 
			
		||||
 | 
			
		||||
    T & operator*() const noexcept;
 | 
			
		||||
    T * operator->() const noexcept;
 | 
			
		||||
    T * get() const noexcept;
 | 
			
		||||
 | 
			
		||||
    explicit operator bool() const noexcept;
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_ptr & b) noexcept;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator==( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator==( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator!=( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool operator!=( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
### element_type
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
Provides the type of the stored pointer.
 | 
			
		||||
 | 
			
		||||
### constructor
 | 
			
		||||
 | 
			
		||||
    explicit scoped_ptr(T * p = 0) noexcept;
 | 
			
		||||
 | 
			
		||||
Constructs a `scoped_ptr`, storing a copy of `p`, which must have been allocated via a
 | 
			
		||||
{cpp} `new` expression or be 0. `T` is not required be a complete type.
 | 
			
		||||
 | 
			
		||||
### destructor
 | 
			
		||||
 | 
			
		||||
    ~scoped_ptr() noexcept;
 | 
			
		||||
 | 
			
		||||
Destroys the object pointed to by the stored pointer, if any, as if by using
 | 
			
		||||
`delete this\->get()`. `T` must be a complete type.
 | 
			
		||||
 | 
			
		||||
### reset
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) noexcept;
 | 
			
		||||
 | 
			
		||||
Deletes the object pointed to by the stored pointer and then stores a copy of
 | 
			
		||||
`p`, which must have been allocated via a {cpp} `new` expression or be 0.
 | 
			
		||||
 | 
			
		||||
Since the previous object needs to be deleted, `T` must be a complete type.
 | 
			
		||||
 | 
			
		||||
### indirection
 | 
			
		||||
 | 
			
		||||
    T & operator*() const noexcept;
 | 
			
		||||
 | 
			
		||||
Returns a reference to the object pointed to by the stored pointer. Behavior is undefined if the stored pointer is 0.
 | 
			
		||||
 | 
			
		||||
    T * operator->() const noexcept;
 | 
			
		||||
 | 
			
		||||
Returns the stored pointer. Behavior is undefined if the stored pointer is 0.
 | 
			
		||||
 | 
			
		||||
### get
 | 
			
		||||
 | 
			
		||||
    T * get() const noexcept;
 | 
			
		||||
 | 
			
		||||
Returns the stored pointer. `T` need not be a complete type.
 | 
			
		||||
 | 
			
		||||
### conversions
 | 
			
		||||
 | 
			
		||||
    explicit operator bool () const noexcept; // never throws
 | 
			
		||||
 | 
			
		||||
Returns `get() != 0`.
 | 
			
		||||
 | 
			
		||||
NOTE: On C++03 compilers, the return value is of an unspecified type.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_ptr & b) noexcept;
 | 
			
		||||
 | 
			
		||||
Exchanges the contents of the two smart pointers. `T` need not be a complete type.
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
 | 
			
		||||
    template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) noexcept;
 | 
			
		||||
 | 
			
		||||
Equivalent to `a.swap(b)`.
 | 
			
		||||
 | 
			
		||||
### comparisons
 | 
			
		||||
 | 
			
		||||
    template<class T> bool operator==( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class T> bool operator==( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;
 | 
			
		||||
 | 
			
		||||
Returns `p.get() == nullptr`.
 | 
			
		||||
 | 
			
		||||
    template<class T> bool operator!=( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class T> bool operator!=( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;
 | 
			
		||||
 | 
			
		||||
Returns `p.get() != nullptr`.
 | 
			
		||||
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
Here's an example that uses `scoped_ptr`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
#include <boost/scoped_ptr.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } };
 | 
			
		||||
 | 
			
		||||
class MyClass {
 | 
			
		||||
    boost::scoped_ptr<int> ptr;
 | 
			
		||||
  public:
 | 
			
		||||
    MyClass() : ptr(new int) { *ptr = 0; }
 | 
			
		||||
    int add_one() { return ++*ptr; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::scoped_ptr<Shoe> x(new Shoe);
 | 
			
		||||
    MyClass my_instance;
 | 
			
		||||
    std::cout << my_instance.add_one() << '\n';
 | 
			
		||||
    std::cout << my_instance.add_one() << '\n';
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The example program produces the beginning of a child's nursery rhyme:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
1
 | 
			
		||||
2
 | 
			
		||||
Buckle my shoe
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Rationale
 | 
			
		||||
 | 
			
		||||
The primary reason to use `scoped_ptr` rather than `std::auto_ptr` or `std::unique_ptr` is to let readers of your code
 | 
			
		||||
know that you intend "resource acquisition is initialization" to be applied only for the current scope, and have no intent to transfer ownership.
 | 
			
		||||
 | 
			
		||||
A secondary reason to use `scoped_ptr` is to prevent a later maintenance programmer from adding a function that transfers
 | 
			
		||||
ownership by returning the `auto_ptr`, because the maintenance programmer saw `auto_ptr`, and assumed ownership could safely be transferred.
 | 
			
		||||
 | 
			
		||||
Think of `bool` vs `int`. We all know that under the covers `bool` is usually just an `int`. Indeed, some argued against including bool in the {cpp}
 | 
			
		||||
standard because of that. But by coding `bool` rather than `int`, you tell your readers what your intent is. Same with `scoped_ptr`; by using it you are signaling intent.
 | 
			
		||||
 | 
			
		||||
It has been suggested that `scoped_ptr<T>` is equivalent to `std::auto_ptr<T> const`. Ed Brey pointed out, however, that `reset` will not work on a `std::auto_ptr<T> const`.
 | 
			
		||||
 | 
			
		||||
## Handle/Body Idiom
 | 
			
		||||
 | 
			
		||||
One common usage of `scoped_ptr` is to implement a handle/body (also called pimpl) idiom which avoids exposing the body (implementation) in the header file.
 | 
			
		||||
 | 
			
		||||
The `link:../../example/scoped_ptr_example_test.cpp[scoped_ptr_example_test.cpp]` sample program includes a header file,
 | 
			
		||||
`link:../../example/scoped_ptr_example.hpp[scoped_ptr_example.hpp]`, which uses a `scoped_ptr<>` to an incomplete type to hide the
 | 
			
		||||
implementation. The instantiation of member functions which require a complete type occurs in the `link:../../example/scoped_ptr_example.cpp[scoped_ptr_example.cpp]`
 | 
			
		||||
implementation file.
 | 
			
		||||
 | 
			
		||||
## Frequently Asked Questions
 | 
			
		||||
 | 
			
		||||
[qanda]
 | 
			
		||||
Why doesn't `scoped_ptr` have a `release()` member?::
 | 
			
		||||
 | 
			
		||||
  When reading source code, it is valuable to be able to draw conclusions about program behavior based on the types being used. If `scoped_ptr` had a `release()` member,
 | 
			
		||||
  it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use `std::auto_ptr` where
 | 
			
		||||
  transfer of ownership is required. (supplied by Dave Abrahams)
 | 
			
		||||
@@ -1,270 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[[shared_array]]
 | 
			
		||||
[appendix]
 | 
			
		||||
# shared_array (deprecated)
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: shared_array_
 | 
			
		||||
 | 
			
		||||
NOTE: This facility is deprecated because a `shared_ptr` to `T[]` or `T[N]`
 | 
			
		||||
is now available, and is superior in every regard.
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The `shared_array` class template stores a pointer to a dynamically allocated
 | 
			
		||||
array. (Dynamically allocated array are allocated with the C++ `new[]`
 | 
			
		||||
expression.) The object pointed to is guaranteed to be deleted when the last
 | 
			
		||||
`shared_array` pointing to it is destroyed or reset.
 | 
			
		||||
 | 
			
		||||
Every `shared_array` meets the _CopyConstructible_ and _Assignable_
 | 
			
		||||
requirements of the {cpp} Standard Library, and so can be used in standard
 | 
			
		||||
library containers. Comparison operators are supplied so that shared_array
 | 
			
		||||
works with the standard library's associative containers.
 | 
			
		||||
 | 
			
		||||
Normally, a `shared_array` cannot correctly hold a pointer to an object that
 | 
			
		||||
has been allocated with the non-array form of `new`. See `shared_ptr` for that
 | 
			
		||||
usage.
 | 
			
		||||
 | 
			
		||||
Because the implementation uses reference counting, cycles of `shared_array`
 | 
			
		||||
instances will not be reclaimed. For example, if `main` holds a shared_array
 | 
			
		||||
to `A`, which directly or indirectly holds a shared_array back to `A`, the use
 | 
			
		||||
count of `A` will be 2. Destruction of the original `shared_array` will leave
 | 
			
		||||
`A` dangling with a use count of 1.
 | 
			
		||||
 | 
			
		||||
A `shared_ptr` to a `std::vector` is an alternative to a `shared_array` that
 | 
			
		||||
is a bit heavier duty but far more flexible.
 | 
			
		||||
 | 
			
		||||
The class template is parameterized on `T`, the type of the object pointed to.
 | 
			
		||||
`shared_array` and most of its member functions place no requirements on `T`;
 | 
			
		||||
it is allowed to be an incomplete type, or `void`. Member functions that do
 | 
			
		||||
place additional requirements (constructors, reset) are explicitly documented
 | 
			
		||||
below.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class shared_array {
 | 
			
		||||
  public:
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit shared_array(T* p = 0);
 | 
			
		||||
    template<class D> shared_array(T* p, D d);
 | 
			
		||||
    shared_array(const shared_array& v) noexcept;
 | 
			
		||||
 | 
			
		||||
    ~shared_array() noexcept;
 | 
			
		||||
 | 
			
		||||
    shared_array& operator=(const shared_array& v) noexcept;
 | 
			
		||||
 | 
			
		||||
    void reset(T* p = 0);
 | 
			
		||||
    template<class D> void reset(T* p, D d);
 | 
			
		||||
 | 
			
		||||
    T& operator[](std::ptrdiff_t n) const noexcept;
 | 
			
		||||
    T* get() const noexcept;
 | 
			
		||||
 | 
			
		||||
    bool unique() const noexcept;
 | 
			
		||||
    long use_count() const noexcept;
 | 
			
		||||
 | 
			
		||||
    explicit operator bool() const noexcept;
 | 
			
		||||
 | 
			
		||||
    void swap(shared_array<T>& v) noexcept;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class T> bool
 | 
			
		||||
    operator==(const shared_array<T>& a, const shared_array<T>& b) noexcept;
 | 
			
		||||
  template<class T> bool
 | 
			
		||||
    operator!=(const shared_array<T>& a, const shared_array<T>& b) noexcept;
 | 
			
		||||
  template<class T> bool
 | 
			
		||||
    operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    void swap(shared_array<T>& a, shared_array<T>& b) noexcept;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
### element_type
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
typedef T element_type;
 | 
			
		||||
```
 | 
			
		||||
Type:: Provides the type of the stored pointer.
 | 
			
		||||
 | 
			
		||||
### Constructors
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
explicit shared_array(T* p = 0);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Constructs a `shared_array`, storing a copy of `p`, which must be a
 | 
			
		||||
pointer to an array that was allocated via a C++ `new[]` expression or be 0.
 | 
			
		||||
Afterwards, the use count is 1 (even if `p == 0`; see `~shared_array`).
 | 
			
		||||
Requires::: `T` is a complete type.
 | 
			
		||||
Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class D> shared_array(T* p, D d);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Constructs a `shared_array`, storing a copy of `p` and of `d`.
 | 
			
		||||
Afterwards, the use count is 1. When the the time comes to delete the array
 | 
			
		||||
pointed to by `p`, the object `d` is used in the statement `d(p)`.
 | 
			
		||||
Requires:::
 | 
			
		||||
* `T` is a complete type.
 | 
			
		||||
* The copy constructor and destructor of `D` must not throw.
 | 
			
		||||
* Invoking the object `d` with parameter `p` must not throw.
 | 
			
		||||
Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
shared_array(const shared_array& v) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Constructs a `shared_array`, as if by storing a copy of the pointer
 | 
			
		||||
stored in `v`. Afterwards, the use count for all copies is 1 more than the
 | 
			
		||||
initial use count.
 | 
			
		||||
Requires::: `T` is a complete type.
 | 
			
		||||
 | 
			
		||||
### Destructor
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
~shared_array() noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Decrements the use count. Then, if the use count is 0, deletes the
 | 
			
		||||
array pointed to by the stored pointer. Note that `delete[]` on a pointer with
 | 
			
		||||
a value of 0 is harmless. 
 | 
			
		||||
 | 
			
		||||
### Assignment
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
shared_array& operator=(const shared_array& v) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Constructs a new `shared_array` as described above, then replaces
 | 
			
		||||
this `shared_array` with the new one, destroying the replaced object.
 | 
			
		||||
Requires::: `T` is a complete type.
 | 
			
		||||
Returns::: `*this`.
 | 
			
		||||
 | 
			
		||||
### reset
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
void reset(T* p = 0);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Constructs a new `shared_array` as described above, then replaces
 | 
			
		||||
this `shared_array` with the new one, destroying the replaced object.
 | 
			
		||||
Requires::: `T` is a complete type.
 | 
			
		||||
Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class D> void reset(T* p, D d);
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Constructs a new `shared_array` as described above, then replaces
 | 
			
		||||
this `shared_array` with the new one, destroying the replaced object.
 | 
			
		||||
Requires:::
 | 
			
		||||
* `T` is a complete type.
 | 
			
		||||
* The copy constructor of `D` must not throw.
 | 
			
		||||
Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called.
 | 
			
		||||
 | 
			
		||||
### Indexing
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
T& operator[](std::ptrdiff_t n) const noexcept;
 | 
			
		||||
```
 | 
			
		||||
Returns::: A reference to element `n` of the array pointed to by the stored
 | 
			
		||||
pointer. Behavior is undefined and almost certainly undesirable if the stored
 | 
			
		||||
pointer is 0, or if `n` is less than 0 or is greater than or equal to the
 | 
			
		||||
number of elements in the array.
 | 
			
		||||
Requires::: `T` is a complete type.
 | 
			
		||||
 | 
			
		||||
### get
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
T* get() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: The stored pointer.
 | 
			
		||||
 | 
			
		||||
### unique
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
bool unique() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `true` if no other `shared_array` is sharing ownership of the
 | 
			
		||||
stored pointer, `false` otherwise.
 | 
			
		||||
 | 
			
		||||
### use_count
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
long use_count() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: The number of `shared_array` objects sharing ownership of the
 | 
			
		||||
stored pointer.
 | 
			
		||||
 | 
			
		||||
### Conversions
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
explicit operator bool() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `get() != 0`.
 | 
			
		||||
Requires::: `T` is a complete type.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
void swap(shared_array<T>& b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Effects::: Exchanges the contents of the two smart pointers.
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
### Comparison
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> bool
 | 
			
		||||
  operator==(const shared_array<T>& a, const shared_array<T>& b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T> bool
 | 
			
		||||
  operator!=(const shared_array<T>& a, const shared_array<T>& b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class T> bool
 | 
			
		||||
  operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: The result of comparing the stored pointers of the two smart
 | 
			
		||||
pointers.
 | 
			
		||||
 | 
			
		||||
NOTE: The `operator<` overload is provided to define an ordering so that
 | 
			
		||||
`shared_array` objects can be used in associative containers such as
 | 
			
		||||
`std::map`. The implementation uses `std::less<T*>` to perform the comparison.
 | 
			
		||||
This ensures that the comparison is handled correctly, since the standard
 | 
			
		||||
mandates that relational operations on pointers are unspecified (5.9
 | 
			
		||||
[expr.rel] paragraph 2) but `std::less` on pointers is well-defined (20.3.3
 | 
			
		||||
[lib.comparisons] paragraph 8).
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T>
 | 
			
		||||
  void swap(shared_array<T>& a, shared_array<T>& b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
::
 | 
			
		||||
Returns::: `a.swap(b)`.
 | 
			
		||||
Requires::: `T` is a complete type.
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,768 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 2003, 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[[techniques]]
 | 
			
		||||
[appendix]
 | 
			
		||||
# Smart Pointer Programming Techniques
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: techniques_
 | 
			
		||||
 | 
			
		||||
[#techniques_incomplete]
 | 
			
		||||
## Using incomplete classes for implementation hiding
 | 
			
		||||
 | 
			
		||||
A proven technique (that works in C, too) for separating interface from implementation is to use a pointer to an incomplete class as an opaque handle:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class FILE;
 | 
			
		||||
 | 
			
		||||
FILE * fopen(char const * name, char const * mode);
 | 
			
		||||
void fread(FILE * f, void * data, size_t size);
 | 
			
		||||
void fclose(FILE * f);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
It is possible to express the above interface using `shared_ptr`, eliminating the need to manually call `fclose`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class FILE;
 | 
			
		||||
 | 
			
		||||
shared_ptr<FILE> fopen(char const * name, char const * mode);
 | 
			
		||||
void fread(shared_ptr<FILE> f, void * data, size_t size);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This technique relies on `shared_ptr`’s ability to execute a custom deleter, eliminating the explicit call to `fclose`, and on the fact that `shared_ptr<X>` can be copied and destroyed when `X` is incomplete.
 | 
			
		||||
 | 
			
		||||
## The "Pimpl" idiom
 | 
			
		||||
 | 
			
		||||
A {cpp} specific variation of the incomplete class pattern is the "Pimpl" idiom. The incomplete class is not exposed to the user; it is hidden behind a forwarding facade. `shared_ptr` can be used to implement a "Pimpl":
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
// file.hpp:
 | 
			
		||||
 | 
			
		||||
class file
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    class impl;
 | 
			
		||||
    shared_ptr<impl> pimpl_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    file(char const * name, char const * mode);
 | 
			
		||||
 | 
			
		||||
    // compiler generated members are fine and useful
 | 
			
		||||
 | 
			
		||||
    void read(void * data, size_t size);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// file.cpp:
 | 
			
		||||
 | 
			
		||||
#include "file.hpp"
 | 
			
		||||
 | 
			
		||||
class file::impl
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    impl(impl const &);
 | 
			
		||||
    impl & operator=(impl const &);
 | 
			
		||||
 | 
			
		||||
    // private data
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    impl(char const * name, char const * mode) { ... }
 | 
			
		||||
    ~impl() { ... }
 | 
			
		||||
    void read(void * data, size_t size) { ... }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
file::file(char const * name, char const * mode): pimpl_(new impl(name, mode))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void file::read(void * data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
    pimpl_->read(data, size);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The key thing to note here is that the compiler-generated copy constructor, assignment operator, and destructor all have a sensible meaning. As a result, `file` is `CopyConstructible` and `Assignable`, allowing its use in standard containers.
 | 
			
		||||
 | 
			
		||||
## Using abstract classes for implementation hiding
 | 
			
		||||
 | 
			
		||||
Another widely used C++ idiom for separating inteface and implementation is to use abstract base classes and factory functions.
 | 
			
		||||
The abstract classes are sometimes called "interfaces" and the pattern is known as "interface-based programming". Again,
 | 
			
		||||
`shared_ptr` can be used as the return type of the factory functions:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
// X.hpp:
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual void f() = 0;
 | 
			
		||||
    virtual void g() = 0;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    ~X() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
shared_ptr<X> createX();
 | 
			
		||||
 | 
			
		||||
// X.cpp:
 | 
			
		||||
 | 
			
		||||
class X_impl: public X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X_impl(X_impl const &);
 | 
			
		||||
    X_impl & operator=(X_impl const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual void f()
 | 
			
		||||
    {
 | 
			
		||||
      // ...
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void g()
 | 
			
		||||
    {
 | 
			
		||||
      // ...
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
shared_ptr<X> createX()
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<X> px(new X_impl);
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
A key property of `shared_ptr` is that the allocation, construction, deallocation, and destruction details are captured at the point of construction, inside the factory function.
 | 
			
		||||
 | 
			
		||||
Note the protected and nonvirtual destructor in the example above. The client code cannot, and does not need to, delete a pointer to `X`; the `shared_ptr<X>` instance returned from `createX` will correctly call `~X_impl`.
 | 
			
		||||
 | 
			
		||||
## Preventing `delete px.get()`
 | 
			
		||||
 | 
			
		||||
It is often desirable to prevent client code from deleting a pointer that is being managed by `shared_ptr`. The previous technique showed one possible approach, using a protected destructor. Another alternative is to use a private deleter:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    ~X();
 | 
			
		||||
 | 
			
		||||
    class deleter;
 | 
			
		||||
    friend class deleter;
 | 
			
		||||
 | 
			
		||||
    class deleter
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        void operator()(X * p) { delete p; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static shared_ptr<X> create()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<X> px(new X, X::deleter());
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Encapsulating allocation details, wrapping factory functions
 | 
			
		||||
 | 
			
		||||
`shared_ptr` can be used in creating {cpp} wrappers over existing C style library interfaces that return raw pointers from their factory functions
 | 
			
		||||
to encapsulate allocation details. As an example, consider this interface, where `CreateX` might allocate `X` from its own private heap, `~X` may
 | 
			
		||||
be inaccessible, or `X` may be incomplete:
 | 
			
		||||
 | 
			
		||||
    X * CreateX();
 | 
			
		||||
    void DestroyX(X *);
 | 
			
		||||
 | 
			
		||||
The only way to reliably destroy a pointer returned by `CreateX` is to call `DestroyX`.
 | 
			
		||||
 | 
			
		||||
Here is how a `shared_ptr`-based wrapper may look like:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<X> createX()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<X> px(CreateX(), DestroyX);
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Client code that calls `createX` still does not need to know how the object has been allocated, but now the destruction is automatic.
 | 
			
		||||
 | 
			
		||||
[#techniques_static]
 | 
			
		||||
## Using a shared_ptr to hold a pointer to a statically allocated object
 | 
			
		||||
 | 
			
		||||
Sometimes it is desirable to create a `shared_ptr` to an already existing object, so that the `shared_ptr` does not attempt to destroy the
 | 
			
		||||
object when there are no more references left. As an example, the factory function:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<X> createX();
 | 
			
		||||
 | 
			
		||||
in certain situations may need to return a pointer to a statically allocated `X` instance.
 | 
			
		||||
 | 
			
		||||
The solution is to use a custom deleter that does nothing:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
struct null_deleter
 | 
			
		||||
{
 | 
			
		||||
    void operator()(void const *) const
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static X x;
 | 
			
		||||
 | 
			
		||||
shared_ptr<X> createX()
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<X> px(&x, null_deleter());
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The same technique works for any object known to outlive the pointer.
 | 
			
		||||
 | 
			
		||||
## Using a shared_ptr to hold a pointer to a COM Object
 | 
			
		||||
 | 
			
		||||
Background: COM objects have an embedded reference count and two member functions that manipulate it. `AddRef()` increments the count.
 | 
			
		||||
`Release()` decrements the count and destroys itself when the count drops to zero.
 | 
			
		||||
 | 
			
		||||
It is possible to hold a pointer to a COM object in a `shared_ptr`:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<IWhatever> make_shared_from_COM(IWhatever * p)
 | 
			
		||||
    {
 | 
			
		||||
        p->AddRef();
 | 
			
		||||
        shared_ptr<IWhatever> pw(p, mem_fn(&IWhatever::Release));
 | 
			
		||||
        return pw;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Note, however, that `shared_ptr` copies created from `pw` will not "register" in the embedded count of the COM object;
 | 
			
		||||
they will share the single reference created in `make_shared_from_COM`. Weak pointers created from `pw` will be invalidated when the last
 | 
			
		||||
`shared_ptr` is destroyed, regardless of whether the COM object itself is still alive.
 | 
			
		||||
 | 
			
		||||
As link:../../../../libs/bind/mem_fn.html#Q3[explained] in the `mem_fn` documentation, you need to `#define BOOST_MEM_FN_ENABLE_STDCALL` first.
 | 
			
		||||
 | 
			
		||||
[#techniques_intrusive]
 | 
			
		||||
## Using a shared_ptr to hold a pointer to an object with an embedded reference count
 | 
			
		||||
 | 
			
		||||
This is a generalization of the above technique. The example assumes that the object implements the two functions required by `<<intrusive_ptr,intrusive_ptr>>`,
 | 
			
		||||
`intrusive_ptr_add_ref` and `intrusive_ptr_release`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> struct intrusive_deleter
 | 
			
		||||
{
 | 
			
		||||
    void operator()(T * p)
 | 
			
		||||
    {
 | 
			
		||||
        if(p) intrusive_ptr_release(p);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
shared_ptr<X> make_shared_from_intrusive(X * p)
 | 
			
		||||
{
 | 
			
		||||
    if(p) intrusive_ptr_add_ref(p);
 | 
			
		||||
    shared_ptr<X> px(p, intrusive_deleter<X>());
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Using a shared_ptr to hold another shared ownership smart pointer
 | 
			
		||||
 | 
			
		||||
One of the design goals of `shared_ptr` is to be used in library interfaces. It is possible to encounter a situation where a library takes a
 | 
			
		||||
`shared_ptr` argument, but the object at hand is being managed by a different reference counted or linked smart pointer.
 | 
			
		||||
 | 
			
		||||
It is possible to exploit `shared_ptr`’s custom deleter feature to wrap this existing smart pointer behind a `shared_ptr` facade:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class P> struct smart_pointer_deleter
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    P p_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    smart_pointer_deleter(P const & p): p_(p)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator()(void const *)
 | 
			
		||||
    {
 | 
			
		||||
        p_.reset();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    P const & get() const
 | 
			
		||||
    {
 | 
			
		||||
        return p_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
shared_ptr<X> make_shared_from_another(another_ptr<X> qx)
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<X> px(qx.get(), smart_pointer_deleter< another_ptr<X> >(qx));
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
One subtle point is that deleters are not allowed to throw exceptions, and the above example as written assumes that `p_.reset()` doesn't throw.
 | 
			
		||||
If this is not the case, `p_.reset();` should be wrapped in a `try {} catch(...) {}` block that ignores exceptions. In the (usually unlikely) event
 | 
			
		||||
when an exception is thrown and ignored, `p_` will be released when the lifetime of the deleter ends. This happens when all references, including
 | 
			
		||||
weak pointers, are destroyed or reset.
 | 
			
		||||
 | 
			
		||||
Another twist is that it is possible, given the above `shared_ptr` instance, to recover the original smart pointer, using `<<shared_ptr_get_deleter,get_deleter>>`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
void extract_another_from_shared(shared_ptr<X> px)
 | 
			
		||||
{
 | 
			
		||||
    typedef smart_pointer_deleter< another_ptr<X> > deleter;
 | 
			
		||||
 | 
			
		||||
    if(deleter const * pd = get_deleter<deleter>(px))
 | 
			
		||||
    {
 | 
			
		||||
        another_ptr<X> qx = pd->get();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // not one of ours
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[#techniques_from_raw]
 | 
			
		||||
## Obtaining a shared_ptr from a raw pointer
 | 
			
		||||
 | 
			
		||||
Sometimes it is necessary to obtain a `shared_ptr` given a raw pointer to an object that is already managed by another `shared_ptr` instance. Example:
 | 
			
		||||
 | 
			
		||||
    void f(X * p)
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<X> px(???);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Inside `f`, we'd like to create a `shared_ptr` to `*p`.
 | 
			
		||||
 | 
			
		||||
In the general case, this problem has no solution. One approach is to modify `f` to take a `shared_ptr`, if possible:
 | 
			
		||||
 | 
			
		||||
    void f(shared_ptr<X> px);
 | 
			
		||||
 | 
			
		||||
The same transformation can be used for nonvirtual member functions, to convert the implicit `this`:
 | 
			
		||||
 | 
			
		||||
    void X::f(int m);
 | 
			
		||||
 | 
			
		||||
would become a free function with a `shared_ptr` first argument:
 | 
			
		||||
 | 
			
		||||
    void f(shared_ptr<X> this_, int m);
 | 
			
		||||
 | 
			
		||||
If `f` cannot be changed, but `X` uses intrusive counting, use `<<techniques_intrusive,make_shared_from_intrusive>>` described above. Or, if it's known that the `shared_ptr` created in `f` will never outlive the object, use <<techniques_static,a null deleter>>.
 | 
			
		||||
 | 
			
		||||
## Obtaining a shared_ptr (weak_ptr) to this in a constructor
 | 
			
		||||
 | 
			
		||||
Some designs require objects to register themselves on construction with a central authority. When the registration routines take a `shared_ptr`, this leads to the question how could a constructor obtain a `shared_ptr` to `this`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    X()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<X> this_(???);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In the general case, the problem cannot be solved. The `X` instance being constructed can be an automatic variable or a static variable; it can be created on the heap:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<X> px(new X);
 | 
			
		||||
 | 
			
		||||
but at construction time, `px` does not exist yet, and it is impossible to create another `shared_ptr` instance that shares ownership with it.
 | 
			
		||||
 | 
			
		||||
Depending on context, if the inner `shared_ptr this_` doesn't need to keep the object alive, use a `null_deleter` as explained <<techniques_static,here>> and <<techniques_weak_without_shared,here>>.
 | 
			
		||||
If `X` is supposed to always live on the heap, and be managed by a `shared_ptr`, use a static factory function:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X() { ... }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static shared_ptr<X> create()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<X> px(new X);
 | 
			
		||||
        // use px as 'this_'
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Obtaining a shared_ptr to this
 | 
			
		||||
 | 
			
		||||
Sometimes it is needed to obtain a `shared_ptr` from `this` in a virtual member function under the assumption that `this` is already managed by a `shared_ptr`.
 | 
			
		||||
The transformations <<techniques_from_raw,described in the previous technique>> cannot be applied.
 | 
			
		||||
 | 
			
		||||
A typical example:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual void f() = 0;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    ~X() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Y
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual shared_ptr<X> getX() = 0;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    ~Y() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// --
 | 
			
		||||
 | 
			
		||||
class impl: public X, public Y
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    impl() { ... }
 | 
			
		||||
 | 
			
		||||
    virtual void f() { ... }
 | 
			
		||||
 | 
			
		||||
    virtual shared_ptr<X> getX()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<X> px(???);
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The solution is to keep a weak pointer to `this` as a member in `impl`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class impl: public X, public Y
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    weak_ptr<impl> weak_this;
 | 
			
		||||
 | 
			
		||||
    impl(impl const &);
 | 
			
		||||
    impl & operator=(impl const &);
 | 
			
		||||
 | 
			
		||||
    impl() { ... }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static shared_ptr<impl> create()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<impl> pi(new impl);
 | 
			
		||||
        pi->weak_this = pi;
 | 
			
		||||
        return pi;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void f() { ... }
 | 
			
		||||
 | 
			
		||||
    virtual shared_ptr<X> getX()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<X> px(weak_this);
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The library now includes a helper class template `<<enable_shared_from_this,enable_shared_from_this>>` that can be used to encapsulate the solution:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class impl: public X, public Y, public enable_shared_from_this<impl>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    impl(impl const &);
 | 
			
		||||
    impl & operator=(impl const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual void f() { ... }
 | 
			
		||||
 | 
			
		||||
    virtual shared_ptr<X> getX()
 | 
			
		||||
    {
 | 
			
		||||
        return shared_from_this();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Note that you no longer need to manually initialize the `weak_ptr` member in `enable_shared_from_this`. Constructing a `shared_ptr` to `impl` takes care of that.
 | 
			
		||||
 | 
			
		||||
## Using shared_ptr as a smart counted handle
 | 
			
		||||
 | 
			
		||||
Some library interfaces use opaque handles, a variation of the <<techniques_incomplete,incomplete class technique>> described above. An example:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
typedef void * HANDLE;
 | 
			
		||||
 | 
			
		||||
HANDLE CreateProcess();
 | 
			
		||||
void CloseHandle(HANDLE);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Instead of a raw pointer, it is possible to use `shared_ptr` as the handle and get reference counting and automatic resource management for free:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
typedef shared_ptr<void> handle;
 | 
			
		||||
 | 
			
		||||
handle createProcess()
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<void> pv(CreateProcess(), CloseHandle);
 | 
			
		||||
    return pv;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Using shared_ptr to execute code on block exit
 | 
			
		||||
 | 
			
		||||
`shared_ptr<void>` can automatically execute cleanup code when control leaves a scope.
 | 
			
		||||
 | 
			
		||||
* Executing `f(p)`, where `p` is a pointer:
 | 
			
		||||
+
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<void> guard(p, f);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* Executing arbitrary code: `f(x, y)`:
 | 
			
		||||
+
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<void> guard(static_cast<void*>(0), bind(f, x, y));
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Using shared_ptr<void> to hold an arbitrary object
 | 
			
		||||
 | 
			
		||||
`shared_ptr<void>` can act as a generic object pointer similar to `void*`. When a `shared_ptr<void>` instance constructed as:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<void> pv(new X);
 | 
			
		||||
 | 
			
		||||
is destroyed, it will correctly dispose of the `X` object by executing `~X`.
 | 
			
		||||
 | 
			
		||||
This propery can be used in much the same manner as a raw `void*` is used to temporarily strip type information from an object pointer.
 | 
			
		||||
A `shared_ptr<void>` can later be cast back to the correct type by using `<<shared_ptr_static_pointer_cast,static_pointer_cast>>`.
 | 
			
		||||
 | 
			
		||||
## Associating arbitrary data with heterogeneous `shared_ptr` instances
 | 
			
		||||
 | 
			
		||||
`shared_ptr` and `weak_ptr` support `operator<` comparisons required by standard associative containers such as `std::map`. This can be
 | 
			
		||||
used to non-intrusively associate arbitrary data with objects managed by `shared_ptr`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
typedef int Data;
 | 
			
		||||
 | 
			
		||||
std::map<shared_ptr<void>, Data> userData;
 | 
			
		||||
// or std::map<weak_ptr<void>, Data> userData; to not affect the lifetime
 | 
			
		||||
 | 
			
		||||
shared_ptr<X> px(new X);
 | 
			
		||||
shared_ptr<int> pi(new int(3));
 | 
			
		||||
 | 
			
		||||
userData[px] = 42;
 | 
			
		||||
userData[pi] = 91;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Using `shared_ptr` as a `CopyConstructible` mutex lock
 | 
			
		||||
 | 
			
		||||
Sometimes it's necessary to return a mutex lock from a function, and a noncopyable lock cannot be returned by value. It is possible to use `shared_ptr` as a mutex lock:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class mutex
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    void lock();
 | 
			
		||||
    void unlock();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
shared_ptr<mutex> lock(mutex & m)
 | 
			
		||||
{
 | 
			
		||||
    m.lock();
 | 
			
		||||
    return shared_ptr<mutex>(&m, mem_fn(&mutex::unlock));
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Better yet, the `shared_ptr` instance acting as a lock can be encapsulated in a dedicated `shared_lock` class:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class shared_lock
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<void> pv;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    template<class Mutex> explicit shared_lock(Mutex & m): pv((m.lock(), &m), mem_fn(&Mutex::unlock)) {}
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`shared_lock` can now be used as:
 | 
			
		||||
 | 
			
		||||
    shared_lock lock(m);
 | 
			
		||||
 | 
			
		||||
Note that `shared_lock` is not templated on the mutex type, thanks to `shared_ptr<void>`’s ability to hide type information.
 | 
			
		||||
 | 
			
		||||
## Using shared_ptr to wrap member function calls
 | 
			
		||||
 | 
			
		||||
`shared_ptr` implements the ownership semantics required from the `Wrap/CallProxy` scheme described in Bjarne Stroustrup's article
 | 
			
		||||
"Wrapping C++ Member Function Calls" (available online at http://www.stroustrup.com/wrapper.pdf). An implementation is given below:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class T> class pointer
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * p_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit pointer(T * p): p_(p)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> operator->() const
 | 
			
		||||
    {
 | 
			
		||||
        p_->prefix();
 | 
			
		||||
        return shared_ptr<T>(p_, mem_fn(&T::suffix));
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    void prefix();
 | 
			
		||||
    void suffix();
 | 
			
		||||
    friend class pointer<X>;
 | 
			
		||||
    
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    void f();
 | 
			
		||||
    void g();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    X x;
 | 
			
		||||
 | 
			
		||||
    pointer<X> px(&x);
 | 
			
		||||
 | 
			
		||||
    px->f();
 | 
			
		||||
    px->g();
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Delayed deallocation
 | 
			
		||||
 | 
			
		||||
In some situations, a single `px.reset()` can trigger an expensive deallocation in a performance-critical region:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class X; // ~X is expensive
 | 
			
		||||
 | 
			
		||||
class Y
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<X> px;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    void f()
 | 
			
		||||
    {
 | 
			
		||||
        px.reset();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The solution is to postpone the potential deallocation by moving `px` to a dedicated free list that can be periodically emptied when performance and response times are not an issue:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
vector< shared_ptr<void> > free_list;
 | 
			
		||||
 | 
			
		||||
class Y
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<X> px;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    void f()
 | 
			
		||||
    {
 | 
			
		||||
        free_list.push_back(px);
 | 
			
		||||
        px.reset();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// periodically invoke free_list.clear() when convenient
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Another variation is to move the free list logic to the construction point by using a delayed deleter:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
struct delayed_deleter
 | 
			
		||||
{
 | 
			
		||||
    template<class T> void operator()(T * p)
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            shared_ptr<void> pv(p);
 | 
			
		||||
            free_list.push_back(pv);
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[#techniques_weak_without_shared]
 | 
			
		||||
## Weak pointers to objects not managed by a shared_ptr
 | 
			
		||||
 | 
			
		||||
Make the object hold a `shared_ptr` to itself, using a `null_deleter`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<X> this_;
 | 
			
		||||
    int i_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit X(int i): this_(this, null_deleter()), i_(i)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // repeat in all constructors (including the copy constructor!)
 | 
			
		||||
 | 
			
		||||
    X(X const & rhs): this_(this, null_deleter()), i_(rhs.i_)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // do not forget to not assign this_ in the copy assignment
 | 
			
		||||
 | 
			
		||||
    X & operator=(X const & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        i_ = rhs.i_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    weak_ptr<X> get_weak_ptr() const { return this_; }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When the object's lifetime ends, `X::this_` will be destroyed, and all weak pointers will automatically expire.
 | 
			
		||||
@@ -1,298 +0,0 @@
 | 
			
		||||
////
 | 
			
		||||
Copyright 1999 Greg Colvin and Beman Dawes
 | 
			
		||||
Copyright 2002 Darin Adler
 | 
			
		||||
Copyright 2002-2005, 2017 Peter Dimov
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 | 
			
		||||
See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
////
 | 
			
		||||
 | 
			
		||||
[#weak_ptr]
 | 
			
		||||
# weak_ptr: Non-owning Observer
 | 
			
		||||
:toc:
 | 
			
		||||
:toc-title:
 | 
			
		||||
:idprefix: weak_ptr_
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
 | 
			
		||||
The `weak_ptr` class template stores a "weak reference" to an object that's already managed by a `shared_ptr`.
 | 
			
		||||
To access the object, a `weak_ptr` can be converted to a `shared_ptr` using the `shared_ptr` constructor taking
 | 
			
		||||
`weak_ptr`, or the `weak_ptr` member function `lock`. When the last `shared_ptr` to the object goes away and the
 | 
			
		||||
object is deleted, the attempt to obtain a `shared_ptr` from the `weak_ptr` instances that refer to the deleted
 | 
			
		||||
object will fail: the constructor will throw an exception of type `boost::bad_weak_ptr`, and `weak_ptr::lock` will
 | 
			
		||||
return an empty `shared_ptr`.
 | 
			
		||||
 | 
			
		||||
Every `weak_ptr` meets the `CopyConstructible` and `Assignable` requirements of the {cpp} Standard Library, and so
 | 
			
		||||
can be used in standard library containers. Comparison operators are supplied so that `weak_ptr` works with the standard
 | 
			
		||||
library's associative containers.
 | 
			
		||||
 | 
			
		||||
`weak_ptr` operations never throw exceptions.
 | 
			
		||||
 | 
			
		||||
The class template is parameterized on `T`, the type of the object pointed to.
 | 
			
		||||
 | 
			
		||||
Compared to `shared_ptr`, `weak_ptr` provides a very limited subset of operations since accessing its stored pointer is
 | 
			
		||||
often dangerous in multithreaded programs, and sometimes unsafe even within a single thread (that is, it may invoke undefined
 | 
			
		||||
behavior.) Pretend for a moment that `weak_ptr` had a get member function that returned a raw pointer, and consider this innocent
 | 
			
		||||
piece of code:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<int> p(new int(5));
 | 
			
		||||
weak_ptr<int> q(p);
 | 
			
		||||
 | 
			
		||||
// some time later
 | 
			
		||||
 | 
			
		||||
if(int * r = q.get())
 | 
			
		||||
{
 | 
			
		||||
    // use *r
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Imagine that after the `if`, but immediately before `r` is used, another thread executes the statement `p.reset()`. Now `r` is a dangling pointer.
 | 
			
		||||
 | 
			
		||||
The solution to this problem is to create a temporary `shared_ptr` from `q`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<int> p(new int(5));
 | 
			
		||||
weak_ptr<int> q(p);
 | 
			
		||||
 | 
			
		||||
// some time later
 | 
			
		||||
 | 
			
		||||
if(shared_ptr<int> r = q.lock())
 | 
			
		||||
{
 | 
			
		||||
    // use *r
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Now `r` holds a reference to the object that was pointed by `q`. Even if `p.reset()` is executed in another thread, the object will stay alive until
 | 
			
		||||
`r` goes out of scope or is reset. By obtaining a `shared_ptr` to the object, we have effectively locked it against destruction.
 | 
			
		||||
 | 
			
		||||
## Synopsis
 | 
			
		||||
 | 
			
		||||
`weak_ptr` is defined in `<boost/smart_ptr/weak_ptr.hpp>`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class weak_ptr {
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    typedef /*see below*/ element_type;
 | 
			
		||||
 | 
			
		||||
    weak_ptr() noexcept;
 | 
			
		||||
 | 
			
		||||
    template<class Y> weak_ptr(shared_ptr<Y> const & r) noexcept;
 | 
			
		||||
    weak_ptr(weak_ptr const & r) noexcept;
 | 
			
		||||
    template<class Y> weak_ptr(weak_ptr<Y> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
    weak_ptr(weak_ptr && r) noexcept;
 | 
			
		||||
 | 
			
		||||
    ~weak_ptr() noexcept;
 | 
			
		||||
 | 
			
		||||
    weak_ptr & operator=(weak_ptr const & r) noexcept;
 | 
			
		||||
    weak_ptr & operator=(weak_ptr && r) noexcept;
 | 
			
		||||
    template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r) noexcept;
 | 
			
		||||
    template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r) noexcept;
 | 
			
		||||
 | 
			
		||||
    long use_count() const noexcept;
 | 
			
		||||
    bool expired() const noexcept;
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> lock() const noexcept;
 | 
			
		||||
 | 
			
		||||
    void reset() noexcept;
 | 
			
		||||
 | 
			
		||||
    void swap(weak_ptr<T> & b) noexcept;
 | 
			
		||||
 | 
			
		||||
    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 T, class U>
 | 
			
		||||
    bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) noexcept;
 | 
			
		||||
 | 
			
		||||
  template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Members
 | 
			
		||||
 | 
			
		||||
### element_type
 | 
			
		||||
```
 | 
			
		||||
typedef ... element_type;
 | 
			
		||||
```
 | 
			
		||||
`element_type` is `T` when `T` is not an array type, and `U` when `T` is `U[]` or `U[N]`.
 | 
			
		||||
 | 
			
		||||
### constructors
 | 
			
		||||
```
 | 
			
		||||
weak_ptr() noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Constructs an empty `weak_ptr`.
 | 
			
		||||
Postconditions:: `use_count() == 0`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
template<class Y> weak_ptr(shared_ptr<Y> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
weak_ptr(weak_ptr const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> weak_ptr(weak_ptr<Y> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: If `r` is empty, constructs an empty `weak_ptr`; otherwise, constructs a `weak_ptr` that shares ownership with `r` as if by storing a copy of the pointer stored in `r`.
 | 
			
		||||
Postconditions:: `use_count() == r.use_count()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
weak_ptr(weak_ptr && r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Constructs a `weak_ptr` that has the value `r` held.
 | 
			
		||||
Postconditions:: `r` is empty.
 | 
			
		||||
 | 
			
		||||
### destructor
 | 
			
		||||
```
 | 
			
		||||
~weak_ptr() noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Destroys this `weak_ptr` but has no effect on the object its stored pointer points to.
 | 
			
		||||
 | 
			
		||||
### assignment
 | 
			
		||||
```
 | 
			
		||||
weak_ptr & operator=(weak_ptr const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
weak_ptr & operator=(weak_ptr && r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `weak_ptr(r).swap(*this)`.
 | 
			
		||||
 | 
			
		||||
NOTE: The implementation is free to meet the effects (and the implied guarantees) via different means, without creating a temporary.
 | 
			
		||||
 | 
			
		||||
### use_count
 | 
			
		||||
```
 | 
			
		||||
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`.
 | 
			
		||||
 | 
			
		||||
### expired
 | 
			
		||||
```
 | 
			
		||||
bool expired() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `use_count() == 0`.
 | 
			
		||||
 | 
			
		||||
### lock
 | 
			
		||||
```
 | 
			
		||||
shared_ptr<T> lock() const noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: `expired()? shared_ptr<T>(): shared_ptr<T>(*this)`.
 | 
			
		||||
 | 
			
		||||
### reset
 | 
			
		||||
```
 | 
			
		||||
void reset() noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `weak_ptr().swap(*this)`.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
```
 | 
			
		||||
void swap(weak_ptr & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Exchanges the contents of the two smart pointers.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
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;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: See the description of `operator<`.
 | 
			
		||||
 | 
			
		||||
## Free Functions
 | 
			
		||||
 | 
			
		||||
### comparison
 | 
			
		||||
```
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
  bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Returns:: An unspecified value such that
 | 
			
		||||
- `operator<` is a strict weak ordering as described in section [lib.alg.sorting] of the {cpp} standard; 
 | 
			
		||||
- under the equivalence relation defined by `operator<`, `!(a < b) && !(b < a)`, two `weak_ptr` instances
 | 
			
		||||
  are equivalent if and only if they share ownership or are both empty.
 | 
			
		||||
 | 
			
		||||
NOTE: Allows `weak_ptr` objects to be used as keys in associative containers.
 | 
			
		||||
 | 
			
		||||
### swap
 | 
			
		||||
```
 | 
			
		||||
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept;
 | 
			
		||||
```
 | 
			
		||||
[none]
 | 
			
		||||
* {blank}
 | 
			
		||||
+
 | 
			
		||||
Effects:: Equivalent to `a.swap(b)`.
 | 
			
		||||
 | 
			
		||||
## Frequently Asked Questions
 | 
			
		||||
 | 
			
		||||
[qanda]
 | 
			
		||||
Can an object create a weak_ptr to itself in its constructor?::
 | 
			
		||||
 | 
			
		||||
  No. A `weak_ptr` can only be created from a `shared_ptr`, and at object construction time no
 | 
			
		||||
  `shared_ptr` to the object exists yet. Even if you could create a temporary `shared_ptr` to `this`,
 | 
			
		||||
  it would go out of scope at the end of the constructor, and all `weak_ptr` instances would instantly expire.
 | 
			
		||||
+
 | 
			
		||||
The solution is to make the constructor private, and supply a factory function that returns a `shared_ptr`:
 | 
			
		||||
+
 | 
			
		||||
```
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X();
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static shared_ptr<X> create()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<X> px(new X);
 | 
			
		||||
        // create weak pointers from px here
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
// Boost scoped_ptr_example_test main program  -------------------------------//
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.  Distributed under the Boost
 | 
			
		||||
//  Software License, Version 1.0. (See accompanying file
 | 
			
		||||
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
#include "scoped_ptr_example.hpp"
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  example my_example;
 | 
			
		||||
  my_example.do_something();
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
// Boost shared_ptr_example2_test main program  ------------------------------//
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.  Distributed under the Boost
 | 
			
		||||
//  Software License, Version 1.0. (See accompanying file
 | 
			
		||||
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
#include "shared_ptr_example2.hpp"
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  example a;
 | 
			
		||||
  a.do_something();
 | 
			
		||||
  example b(a);
 | 
			
		||||
  b.do_something();
 | 
			
		||||
  example c;
 | 
			
		||||
  c = a;
 | 
			
		||||
  c.do_something();
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -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,82 +0,0 @@
 | 
			
		||||
#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.
 | 
			
		||||
//  Copyright (c) 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/bind.hpp>
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/lightweight_thread.hpp>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
int const n = 1024 * 1024;
 | 
			
		||||
 | 
			
		||||
void test( boost::shared_ptr<int> const & pi )
 | 
			
		||||
{
 | 
			
		||||
    std::vector< boost::shared_ptr<int> > v;
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < n; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        v.push_back( pi );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int const m = 16; // threads
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_PTHREADS )
 | 
			
		||||
 | 
			
		||||
char const * thmodel = "POSIX";
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
char const * thmodel = "Windows";
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    using namespace std; // printf, clock_t, clock
 | 
			
		||||
 | 
			
		||||
    printf( "Using %s threads: %d threads, %d iterations: ", thmodel, m, n );
 | 
			
		||||
 | 
			
		||||
    boost::shared_ptr<int> pi( new int(42) );
 | 
			
		||||
 | 
			
		||||
    clock_t t = clock();
 | 
			
		||||
 | 
			
		||||
    boost::detail::lw_thread_t a[ m ];
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < m; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_create( a[ i ], boost::bind( test, pi ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for( int j = 0; j < m; ++j )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_join( a[j] );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    t = clock() - t;
 | 
			
		||||
 | 
			
		||||
    printf( "\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC );
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
 | 
			
		||||
int const n = 8 * 1024 * 1024;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    using namespace std;
 | 
			
		||||
 | 
			
		||||
    std::vector< boost::shared_ptr<int> > v;
 | 
			
		||||
    boost::shared_ptr<int> pi(new int);
 | 
			
		||||
 | 
			
		||||
    clock_t t = clock();
 | 
			
		||||
 | 
			
		||||
    for(int i = 0; i < n; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        v.push_back(pi);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    t = clock() - t;
 | 
			
		||||
 | 
			
		||||
    std::cout << static_cast<double>(t) / CLOCKS_PER_SEC << '\n';
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,247 +0,0 @@
 | 
			
		||||
 | 
			
		||||
// Copyright (c) 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
// See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/bind.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/thread/shared_mutex.hpp>
 | 
			
		||||
#include <boost/thread/locks.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/lightweight_mutex.hpp>
 | 
			
		||||
#include <boost/detail/lightweight_thread.hpp>
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <numeric>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
static void next_value( unsigned & v )
 | 
			
		||||
{
 | 
			
		||||
    v = v % 2? 3 * v + 1: v / 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct X
 | 
			
		||||
{
 | 
			
		||||
    std::vector<unsigned> v_;
 | 
			
		||||
 | 
			
		||||
    explicit X( std::size_t n ): v_( n )
 | 
			
		||||
    {
 | 
			
		||||
        for( std::size_t i = 0; i < n; ++i )
 | 
			
		||||
        {
 | 
			
		||||
            v_[ i ] = i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned get() const
 | 
			
		||||
    {
 | 
			
		||||
        return std::accumulate( v_.begin(), v_.end(), 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set()
 | 
			
		||||
    {
 | 
			
		||||
        std::for_each( v_.begin(), v_.end(), next_value );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static boost::shared_ptr<X> ps;
 | 
			
		||||
 | 
			
		||||
static boost::detail::lightweight_mutex lm;
 | 
			
		||||
static boost::shared_mutex rw;
 | 
			
		||||
 | 
			
		||||
enum prim_type
 | 
			
		||||
{
 | 
			
		||||
    pt_mutex,
 | 
			
		||||
    pt_rwlock,
 | 
			
		||||
    pt_atomics
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int read_access( prim_type pt )
 | 
			
		||||
{
 | 
			
		||||
    switch( pt )
 | 
			
		||||
    {
 | 
			
		||||
    case pt_mutex:
 | 
			
		||||
        {
 | 
			
		||||
            boost::detail::lightweight_mutex::scoped_lock lock( lm );
 | 
			
		||||
            return ps->get();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    case pt_rwlock:
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_lock<boost::shared_mutex> lock( rw );
 | 
			
		||||
            return ps->get();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    case pt_atomics:
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr<X> p2 = boost::atomic_load( &ps );
 | 
			
		||||
            return p2->get();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void write_access( prim_type pt )
 | 
			
		||||
{
 | 
			
		||||
    switch( pt )
 | 
			
		||||
    {
 | 
			
		||||
    case pt_mutex:
 | 
			
		||||
        {
 | 
			
		||||
            boost::detail::lightweight_mutex::scoped_lock lock( lm );
 | 
			
		||||
            ps->set();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case pt_rwlock:
 | 
			
		||||
        {
 | 
			
		||||
            boost::unique_lock<boost::shared_mutex> lock( rw );
 | 
			
		||||
            ps->set();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case pt_atomics:
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr<X> p1 = boost::atomic_load( &ps );
 | 
			
		||||
 | 
			
		||||
            for( ;; )
 | 
			
		||||
            {
 | 
			
		||||
                boost::shared_ptr<X> p2( new X( *p1 ) );
 | 
			
		||||
                p2->set();
 | 
			
		||||
 | 
			
		||||
                if( boost::atomic_compare_exchange( &ps, &p1, p2 ) ) break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void worker( int k, prim_type pt, int n, int r )
 | 
			
		||||
{
 | 
			
		||||
    ++r;
 | 
			
		||||
 | 
			
		||||
    unsigned s = 0, nr = 0, nw = 0;
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < n; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        if( i % r )
 | 
			
		||||
        {
 | 
			
		||||
            s += read_access( pt );
 | 
			
		||||
            ++nr;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            write_access( pt );
 | 
			
		||||
            ++s;
 | 
			
		||||
            ++nw;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf( "Worker %2d: %u:%u, %10u\n", k, nr, nw, s );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_PTHREADS )
 | 
			
		||||
  char const * thmodel = "POSIX";
 | 
			
		||||
#else
 | 
			
		||||
  char const * thmodel = "Windows";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
char const * pt_to_string( prim_type pt )
 | 
			
		||||
{
 | 
			
		||||
    switch( pt )
 | 
			
		||||
    {
 | 
			
		||||
    case pt_mutex:
 | 
			
		||||
 | 
			
		||||
        return "mutex";
 | 
			
		||||
 | 
			
		||||
    case pt_rwlock:
 | 
			
		||||
 | 
			
		||||
        return "rwlock";
 | 
			
		||||
 | 
			
		||||
    case pt_atomics:
 | 
			
		||||
 | 
			
		||||
        return "atomics";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_pt_option( std::string const & opt, prim_type & pt, prim_type pt2 )
 | 
			
		||||
{
 | 
			
		||||
    if( opt == pt_to_string( pt2 ) )
 | 
			
		||||
    {
 | 
			
		||||
        pt = pt2;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_int_option( std::string const & opt, std::string const & prefix, int & k, int kmin, int kmax )
 | 
			
		||||
{
 | 
			
		||||
    if( opt.substr( 0, prefix.size() ) == prefix )
 | 
			
		||||
    {
 | 
			
		||||
        int v = atoi( opt.substr( prefix.size() ).c_str() );
 | 
			
		||||
 | 
			
		||||
        if( v >= kmin && v <= kmax )
 | 
			
		||||
        {
 | 
			
		||||
            k = v;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main( int ac, char const * av[] )
 | 
			
		||||
{
 | 
			
		||||
    using namespace std; // printf, clock_t, clock
 | 
			
		||||
 | 
			
		||||
    int m = 4;          // threads
 | 
			
		||||
    int n = 10000;      // vector size
 | 
			
		||||
    int k = 1000000;    // iterations
 | 
			
		||||
    int r = 100;        // read/write ratio, r:1
 | 
			
		||||
 | 
			
		||||
    prim_type pt = pt_atomics;
 | 
			
		||||
 | 
			
		||||
    for( int i = 1; i < ac; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        handle_pt_option( av[i], pt, pt_mutex );
 | 
			
		||||
        handle_pt_option( av[i], pt, pt_rwlock );
 | 
			
		||||
        handle_pt_option( av[i], pt, pt_atomics );
 | 
			
		||||
 | 
			
		||||
        handle_int_option( av[i], "n=", n, 1, INT_MAX );
 | 
			
		||||
        handle_int_option( av[i], "size=", n, 1, INT_MAX );
 | 
			
		||||
 | 
			
		||||
        handle_int_option( av[i], "k=", k, 1, INT_MAX );
 | 
			
		||||
        handle_int_option( av[i], "iterations=", k, 1, INT_MAX );
 | 
			
		||||
 | 
			
		||||
        handle_int_option( av[i], "m=", m, 1, INT_MAX );
 | 
			
		||||
        handle_int_option( av[i], "threads=", m, 1, INT_MAX );
 | 
			
		||||
 | 
			
		||||
        handle_int_option( av[i], "r=", r, 1, INT_MAX );
 | 
			
		||||
        handle_int_option( av[i], "ratio=", r, 1, INT_MAX );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf( "%s: threads=%d size=%d iterations=%d ratio=%d %s\n\n", thmodel, m, n, k, r, pt_to_string( pt ) );
 | 
			
		||||
 | 
			
		||||
    ps.reset( new X( n ) );
 | 
			
		||||
 | 
			
		||||
    clock_t t = clock();
 | 
			
		||||
 | 
			
		||||
    std::vector<boost::detail::lw_thread_t> a( m );
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < m; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_create( a[ i ], boost::bind( worker, i, pt, k, r ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for( int j = 0; j < m; ++j )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_join( a[ j ] );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    t = clock() - t;
 | 
			
		||||
 | 
			
		||||
    double ts = static_cast<double>( t ) / CLOCKS_PER_SEC;
 | 
			
		||||
    printf( "%.3f seconds, %.3f accesses per microsecond.\n", ts, m * k / ts / 1e+6 );
 | 
			
		||||
}
 | 
			
		||||
@@ -1,191 +0,0 @@
 | 
			
		||||
 | 
			
		||||
// Copyright (c) 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
// See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
//#define USE_MUTEX
 | 
			
		||||
//#define USE_RWLOCK
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/bind.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( USE_RWLOCK )
 | 
			
		||||
#include <boost/thread/shared_mutex.hpp>
 | 
			
		||||
#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 <cstdio>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
int const n = 1024 * 1024;
 | 
			
		||||
 | 
			
		||||
struct X
 | 
			
		||||
{
 | 
			
		||||
    int v_; // version
 | 
			
		||||
 | 
			
		||||
    unsigned a_;
 | 
			
		||||
    unsigned b_;
 | 
			
		||||
 | 
			
		||||
    X(): v_( 0 ), a_( 1 ), b_( 1 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int get() const
 | 
			
		||||
    {
 | 
			
		||||
        return a_ * 7 + b_ * 11;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set()
 | 
			
		||||
    {
 | 
			
		||||
        int tmp = get();
 | 
			
		||||
 | 
			
		||||
        b_ = a_;
 | 
			
		||||
        a_ = tmp;
 | 
			
		||||
 | 
			
		||||
        ++v_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static boost::shared_ptr<X> ps( new X );
 | 
			
		||||
 | 
			
		||||
static boost::detail::lightweight_mutex lm;
 | 
			
		||||
 | 
			
		||||
#if defined( USE_RWLOCK )
 | 
			
		||||
static boost::shared_mutex rw;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int tr = 0;
 | 
			
		||||
 | 
			
		||||
void reader( int r )
 | 
			
		||||
{
 | 
			
		||||
    int k = 0;
 | 
			
		||||
    unsigned s = 0;
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < n; ++k )
 | 
			
		||||
    {
 | 
			
		||||
#if defined( USE_MUTEX )
 | 
			
		||||
 | 
			
		||||
        boost::detail::lightweight_mutex::scoped_lock lock( lm );
 | 
			
		||||
 | 
			
		||||
        s += ps->get();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( ps->v_ >= i );
 | 
			
		||||
        i = ps->v_;
 | 
			
		||||
 | 
			
		||||
#elif defined( USE_RWLOCK )
 | 
			
		||||
 | 
			
		||||
        boost::shared_lock<boost::shared_mutex> lock( rw );
 | 
			
		||||
 | 
			
		||||
        s += ps->get();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( ps->v_ >= i );
 | 
			
		||||
        i = ps->v_;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        boost::shared_ptr<X> p2 = boost::atomic_load( &ps );
 | 
			
		||||
 | 
			
		||||
        s += p2->get();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( p2->v_ >= i );
 | 
			
		||||
        i = p2->v_;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf( "Reader %d: %9d iterations (%6.3fx), %u\n", r, k, (double)k / n, s );
 | 
			
		||||
 | 
			
		||||
    boost::detail::lightweight_mutex::scoped_lock lock( lm );
 | 
			
		||||
    tr += k;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void writer()
 | 
			
		||||
{
 | 
			
		||||
    for( int i = 0; i < n; ++i )
 | 
			
		||||
    {
 | 
			
		||||
#if defined( USE_MUTEX )
 | 
			
		||||
 | 
			
		||||
        boost::detail::lightweight_mutex::scoped_lock lock( lm );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( ps->v_ == i );
 | 
			
		||||
        ps->set();
 | 
			
		||||
 | 
			
		||||
#elif defined( USE_RWLOCK )
 | 
			
		||||
 | 
			
		||||
        boost::unique_lock<boost::shared_mutex> lock( rw );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( ps->v_ == i );
 | 
			
		||||
        ps->set();
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        boost::shared_ptr<X> p2( new X( *ps ) );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( p2->v_ == i );
 | 
			
		||||
        p2->set();
 | 
			
		||||
 | 
			
		||||
        boost::atomic_store( &ps, p2 );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_PTHREADS )
 | 
			
		||||
  char const * thmodel = "POSIX";
 | 
			
		||||
#else
 | 
			
		||||
  char const * thmodel = "Windows";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int const mr = 8; // reader threads
 | 
			
		||||
int const mw = 1; // writer thread
 | 
			
		||||
 | 
			
		||||
#if defined( USE_MUTEX )
 | 
			
		||||
  char const * prim = "mutex";
 | 
			
		||||
#elif defined( USE_RWLOCK )
 | 
			
		||||
  char const * prim = "rwlock";
 | 
			
		||||
#else
 | 
			
		||||
  char const * prim = "atomics";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    using namespace std; // printf, clock_t, clock
 | 
			
		||||
 | 
			
		||||
    printf( "Using %s threads: %dR + %dW threads, %d iterations, %s\n\n", thmodel, mr, mw, n, prim );
 | 
			
		||||
 | 
			
		||||
    clock_t t = clock();
 | 
			
		||||
 | 
			
		||||
    boost::detail::lw_thread_t a[ mr+mw ];
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < mr; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_create( a[ i ], boost::bind( reader, i ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for( int i = mr; i < mr+mw; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_create( a[ i ], writer );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for( int j = 0; j < mr+mw; ++j )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_join( a[ j ] );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    t = clock() - t;
 | 
			
		||||
 | 
			
		||||
    double ts = static_cast<double>( t ) / CLOCKS_PER_SEC;
 | 
			
		||||
    printf( "%.3f seconds, %.3f reads per microsecond.\n", ts, tr / ts / 1e+6 );
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,122 +0,0 @@
 | 
			
		||||
#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.
 | 
			
		||||
//  Copyright 2005, 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
#include <boost/bind.hpp>
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/lightweight_thread.hpp>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
int const n = 16384;
 | 
			
		||||
int const k = 512; // vector size
 | 
			
		||||
int const m = 16; // threads
 | 
			
		||||
 | 
			
		||||
void test( std::vector< boost::shared_ptr<int> > & v )
 | 
			
		||||
{
 | 
			
		||||
    using namespace std; // printf, rand
 | 
			
		||||
 | 
			
		||||
    std::vector< boost::weak_ptr<int> > w( v.begin(), v.end() );
 | 
			
		||||
 | 
			
		||||
    int s = 0, f = 0, r = 0;
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < n; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        // randomly kill a pointer
 | 
			
		||||
 | 
			
		||||
        v[ rand() % k ].reset();
 | 
			
		||||
        ++s;
 | 
			
		||||
 | 
			
		||||
        for( int j = 0; j < k; ++j )
 | 
			
		||||
        {
 | 
			
		||||
            if( boost::shared_ptr<int> px = w[ j ].lock() )
 | 
			
		||||
            {
 | 
			
		||||
                ++s;
 | 
			
		||||
 | 
			
		||||
                if( rand() & 4 )
 | 
			
		||||
                {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // rebind anyway with prob. 50% for add_ref_lock() against weak_release() contention
 | 
			
		||||
                ++f;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                ++r;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            w[ j ] = v[ rand() % k ];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf( "\n%d locks, %d forced rebinds, %d normal rebinds.", s, f, r );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_PTHREADS )
 | 
			
		||||
 | 
			
		||||
char const * thmodel = "POSIX";
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
char const * thmodel = "Windows";
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    using namespace std; // printf, clock_t, clock
 | 
			
		||||
 | 
			
		||||
    printf("Using %s threads: %d threads, %d * %d iterations: ", thmodel, m, n, k );
 | 
			
		||||
 | 
			
		||||
    std::vector< boost::shared_ptr<int> > v( k );
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < k; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        v[ i ].reset( new int( 0 ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clock_t t = clock();
 | 
			
		||||
 | 
			
		||||
    boost::detail::lw_thread_t a[ m ];
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < m; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_create( a[ i ], boost::bind( test, v ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    v.resize( 0 ); // kill original copies
 | 
			
		||||
 | 
			
		||||
    for( int j = 0; j < m; ++j )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::lw_thread_join( a[j] );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    t = clock() - t;
 | 
			
		||||
 | 
			
		||||
    printf("\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,85 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
int const n = 29000;
 | 
			
		||||
int const k = 2048;
 | 
			
		||||
 | 
			
		||||
void test( std::vector< boost::shared_ptr<int> > & v )
 | 
			
		||||
{
 | 
			
		||||
    using namespace std; // printf, rand
 | 
			
		||||
 | 
			
		||||
    std::vector< boost::weak_ptr<int> > w( v.begin(), v.end() );
 | 
			
		||||
 | 
			
		||||
    int s = 0, r = 0;
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < n; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        // randomly kill a pointer
 | 
			
		||||
 | 
			
		||||
        v[ rand() % k ].reset();
 | 
			
		||||
 | 
			
		||||
        for( int j = 0; j < k; ++j )
 | 
			
		||||
        {
 | 
			
		||||
            if( boost::shared_ptr<int> px = w[ j ].lock() )
 | 
			
		||||
            {
 | 
			
		||||
                ++s;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                ++r;
 | 
			
		||||
                w[ j ] = v[ rand() % k ];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf( "\n%d locks, %d rebinds.", s, r );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    using namespace std; // printf, clock_t, clock
 | 
			
		||||
 | 
			
		||||
    std::vector< boost::shared_ptr<int> > v( k );
 | 
			
		||||
 | 
			
		||||
    for( int i = 0; i < k; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        v[ i ].reset( new int( 0 ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clock_t t = clock();
 | 
			
		||||
 | 
			
		||||
    test( v );
 | 
			
		||||
 | 
			
		||||
    t = clock() - t;
 | 
			
		||||
 | 
			
		||||
    printf( "\n\n%.3f seconds.\n", static_cast<double>( t ) / CLOCKS_PER_SEC );
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								gccspeed.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gccspeed.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 6.4 KiB  | 
@@ -1,21 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count.hpp - thread/SMP safe reference counter
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lightweight_mutex.hpp - lightweight mutex
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
@@ -1,188 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  boost/detail/lightweight_thread.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright (c) 2008, 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" 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
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/quick_allocator.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2003 David Abrahams
 | 
			
		||||
//  Copyright (c) 2003 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/quick_allocator.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  enable_shared_from_this.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/enable_shared_from_this.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
#ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_INTRUSIVE_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  intrusive_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
#ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
#define BOOST_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//  make_shared.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2007, 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/make_shared.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2014 Glen Joseph Fernandes
 | 
			
		||||
(glenjofe@gmail.com)
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
(http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
*/
 | 
			
		||||
#ifndef BOOST_MAKE_UNIQUE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_MAKE_UNIQUE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/make_unique.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,122 +0,0 @@
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// (C) Copyright Ion Gaztanaga 2005. 
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. 
 | 
			
		||||
// (See accompanying file LICENSE_1_0.txt or copy at 
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_POINTER_CAST_HPP
 | 
			
		||||
#define BOOST_POINTER_CAST_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost { 
 | 
			
		||||
 | 
			
		||||
//static_pointer_cast overload for raw pointers
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
inline T* static_pointer_cast(U *ptr) BOOST_SP_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
 | 
			
		||||
{  
 | 
			
		||||
   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
 | 
			
		||||
{  
 | 
			
		||||
   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
 | 
			
		||||
{  
 | 
			
		||||
   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;
 | 
			
		||||
 | 
			
		||||
//dynamic_pointer_cast overload for std::shared_ptr
 | 
			
		||||
using std::dynamic_pointer_cast;
 | 
			
		||||
 | 
			
		||||
//const_pointer_cast overload for std::shared_ptr
 | 
			
		||||
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
 | 
			
		||||
{
 | 
			
		||||
    (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
    typedef typename std::shared_ptr<T>::element_type E;
 | 
			
		||||
 | 
			
		||||
    E * p = reinterpret_cast< E* >( r.get() );
 | 
			
		||||
    return std::shared_ptr<T>( r, p );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//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
 | 
			
		||||
{
 | 
			
		||||
    (void) static_cast< T* >( static_cast< U* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
    typedef typename std::unique_ptr<T>::element_type E;
 | 
			
		||||
 | 
			
		||||
    return std::unique_ptr<T>( static_cast<E*>( r.release() ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//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
 | 
			
		||||
{
 | 
			
		||||
    (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." );
 | 
			
		||||
 | 
			
		||||
    T * p = dynamic_cast<T*>( r.get() );
 | 
			
		||||
    if( p ) r.release();
 | 
			
		||||
    return std::unique_ptr<T>( p );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//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
 | 
			
		||||
{
 | 
			
		||||
    (void) const_cast< T* >( static_cast< U* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
    typedef typename std::unique_ptr<T>::element_type E;
 | 
			
		||||
 | 
			
		||||
    return std::unique_ptr<T>( const_cast<E*>( r.release() ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//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
 | 
			
		||||
{
 | 
			
		||||
    (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
    typedef typename std::unique_ptr<T>::element_type E;
 | 
			
		||||
 | 
			
		||||
    return std::unique_ptr<T>( reinterpret_cast<E*>( r.release() ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #if !defined( BOOST_NO_CXX11_SMART_PTR )
 | 
			
		||||
 | 
			
		||||
#endif   //BOOST_POINTER_CAST_HPP
 | 
			
		||||
@@ -1,55 +0,0 @@
 | 
			
		||||
#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
 | 
			
		||||
#define BOOST_POINTER_TO_OTHER_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  pointer_to_other.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Ion Gaztanaga 2005.
 | 
			
		||||
//  Copyright (c) 2005 Peter Dimov.
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//
 | 
			
		||||
//  (See accompanying file LICENSE_1_0.txt or copy at 
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// Defines the same pointer type (raw or smart) to another pointee type
 | 
			
		||||
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
struct pointer_to_other;
 | 
			
		||||
 | 
			
		||||
template<class T, class U, 
 | 
			
		||||
         template<class> class Sp>
 | 
			
		||||
struct pointer_to_other< Sp<T>, U >
 | 
			
		||||
{
 | 
			
		||||
   typedef Sp<U> type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class T2, class U, 
 | 
			
		||||
         template<class, class> class Sp>
 | 
			
		||||
struct pointer_to_other< Sp<T, T2>, U >
 | 
			
		||||
{
 | 
			
		||||
   typedef Sp<U, T2> type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class T2, class T3, class U, 
 | 
			
		||||
         template<class, class, class> class Sp>
 | 
			
		||||
struct pointer_to_other< Sp<T, T2, T3>, U >
 | 
			
		||||
{
 | 
			
		||||
   typedef Sp<U, T2, T3> type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
struct pointer_to_other< T*, U >
 | 
			
		||||
{
 | 
			
		||||
   typedef U* type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SCOPED_ARRAY_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/scoped_array.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SCOPED_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/scoped_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SHARED_ARRAY_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  shared_array.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/shared_array.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  shared_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001-2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
@@ -1,26 +1,398 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_HPP_INCLUDED
 | 
			
		||||
//  Boost smart_ptr.hpp header file  -----------------------------------------//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  smart_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  For convenience, this header includes the rest of the smart
 | 
			
		||||
//  pointer library headers.
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2003 Peter Dimov  Distributed under the Boost
 | 
			
		||||
//  Software License, Version 1.0. (See accompanying file
 | 
			
		||||
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. Permission to copy,
 | 
			
		||||
//  use, modify, sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided "as is"
 | 
			
		||||
//  without express or implied warranty, and with no claim as to its
 | 
			
		||||
//  suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  21 May 01  Require complete type where incomplete type is unsafe.
 | 
			
		||||
//             (suggested by Vladimir Prus)
 | 
			
		||||
//  21 May 01  operator= fails if operand transitively owned by *this, as in a
 | 
			
		||||
//             linked list (report by Ken Johnson, fix by Beman Dawes)
 | 
			
		||||
//  21 Jan 01  Suppress some useless warnings with MSVC (David Abrahams)
 | 
			
		||||
//  19 Oct 00  Make shared_ptr ctor from auto_ptr explicit. (Robert Vugts) 
 | 
			
		||||
//  24 Jul 00  Change throw() to // never throws.  See lib guidelines
 | 
			
		||||
//             Exception-specification rationale. (Beman Dawes)
 | 
			
		||||
//  22 Jun 00  Remove #if continuations to fix GCC 2.95.2 problem (Beman Dawes)
 | 
			
		||||
//   1 Feb 00  Additional shared_ptr BOOST_NO_MEMBER_TEMPLATES workarounds
 | 
			
		||||
//             (Dave Abrahams)
 | 
			
		||||
//  31 Dec 99  Condition tightened for no member template friend workaround
 | 
			
		||||
//             (Dave Abrahams)
 | 
			
		||||
//  30 Dec 99  Moved BOOST_NMEMBER_TEMPLATES compatibility code to config.hpp
 | 
			
		||||
//             (Dave Abrahams)
 | 
			
		||||
//  30 Nov 99  added operator ==, operator !=, and std::swap and std::less
 | 
			
		||||
//             specializations for shared types (Darin Adler)
 | 
			
		||||
//  11 Oct 99  replaced op[](int) with op[](std::size_t) (Ed Brey, Valentin
 | 
			
		||||
//             Bonnard), added shared_ptr workaround for no member template
 | 
			
		||||
//             friends (Matthew Langston)
 | 
			
		||||
//  25 Sep 99  added shared_ptr::swap and shared_array::swap (Luis Coelho).
 | 
			
		||||
//  20 Jul 99  changed name to smart_ptr.hpp, #include <boost/config.hpp>,
 | 
			
		||||
//             #include <boost/utility.hpp> and use boost::noncopyable
 | 
			
		||||
//  17 May 99  remove scoped_array and shared_array operator*() as
 | 
			
		||||
//             unnecessary (Beman Dawes)
 | 
			
		||||
//  14 May 99  reorder code so no effects when bad_alloc thrown (Abrahams/Dawes)
 | 
			
		||||
//  13 May 99  remove certain throw() specifiers to avoid generated try/catch
 | 
			
		||||
//             code cost (Beman Dawes)
 | 
			
		||||
//  11 May 99  get() added, conversion to T* placed in macro guard (Valentin
 | 
			
		||||
//             Bonnard, Dave Abrahams, and others argued for elimination
 | 
			
		||||
//             of the automatic conversion)
 | 
			
		||||
//  28 Apr 99  #include <memory> fix (Valentin Bonnard)
 | 
			
		||||
//  28 Apr 99  rename transfer() to share() for clarity (Dave Abrahams)
 | 
			
		||||
//  28 Apr 99  remove unsafe shared_array template conversions(Valentin Bonnard)
 | 
			
		||||
//  28 Apr 99  p(r) changed to p(r.px) for clarity (Dave Abrahams)
 | 
			
		||||
//  21 Apr 99  reset() self assignment fix (Valentin Bonnard)
 | 
			
		||||
//  21 Apr 99  dispose() provided to improve clarity (Valentin Bonnard)
 | 
			
		||||
//  27 Apr 99  leak when new throws fixes (Dave Abrahams)
 | 
			
		||||
//  21 Oct 98  initial Version (Greg Colvin/Beman Dawes)
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_SMART_PTR_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>   // for broken compiler workarounds
 | 
			
		||||
#include <cstddef>            // for std::size_t
 | 
			
		||||
#include <memory>             // for std::auto_ptr
 | 
			
		||||
#include <algorithm>          // for std::swap
 | 
			
		||||
#include <boost/utility.hpp>  // for boost::noncopyable, checked_delete, checked_array_delete
 | 
			
		||||
#include <functional>         // for std::less
 | 
			
		||||
#include <boost/static_assert.hpp> // for BOOST_STATIC_ASSERT
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
 | 
			
		||||
# pragma warning(push)
 | 
			
		||||
# pragma warning(disable:4284) // return type for 'identifier::operator->' is not a UDT or reference to a UDT. Will produce errors if applied using infix notation
 | 
			
		||||
#endif    
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
//  scoped_ptr  --------------------------------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  scoped_ptr mimics a built-in pointer except that it guarantees deletion
 | 
			
		||||
//  of the object pointed to, either on destruction of the scoped_ptr or via
 | 
			
		||||
//  an explicit reset().  scoped_ptr is a simple solution for simple needs;
 | 
			
		||||
//  see shared_ptr (below) or std::auto_ptr if your needs are more complex.
 | 
			
		||||
 | 
			
		||||
template<typename T> class scoped_ptr : noncopyable {
 | 
			
		||||
 | 
			
		||||
  T* ptr;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  typedef T element_type;
 | 
			
		||||
 | 
			
		||||
  explicit scoped_ptr( T* p=0 ) : ptr(p) {}  // never throws
 | 
			
		||||
  ~scoped_ptr()                 { checked_delete(ptr); }
 | 
			
		||||
  void reset( T* p=0 )          { if ( ptr != p ) { checked_delete(ptr); ptr = p; } }
 | 
			
		||||
  T& operator*() const          { return *ptr; }  // never throws
 | 
			
		||||
  T* operator->() const         { return ptr; }  // never throws
 | 
			
		||||
  T* get() const                { return ptr; }  // never throws
 | 
			
		||||
#ifdef BOOST_SMART_PTR_CONVERSION
 | 
			
		||||
  // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
 | 
			
		||||
  operator T*() const           { return ptr; }  // never throws 
 | 
			
		||||
#endif
 | 
			
		||||
  };  // scoped_ptr
 | 
			
		||||
 | 
			
		||||
//  scoped_array  ------------------------------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
 | 
			
		||||
//  is guaranteed, either on destruction of the scoped_array or via an explicit
 | 
			
		||||
//  reset(). See shared_array or std::vector if your needs are more complex.
 | 
			
		||||
 | 
			
		||||
template<typename T> class scoped_array : noncopyable {
 | 
			
		||||
 | 
			
		||||
  T* ptr;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  typedef T element_type;
 | 
			
		||||
 | 
			
		||||
  explicit scoped_array( T* p=0 ) : ptr(p) {}  // never throws
 | 
			
		||||
  ~scoped_array()                    { checked_array_delete(ptr); }
 | 
			
		||||
 | 
			
		||||
  void reset( T* p=0 )               { if ( ptr != p )
 | 
			
		||||
                                         {checked_array_delete(ptr); ptr=p;} }
 | 
			
		||||
 | 
			
		||||
  T* get() const                     { return ptr; }  // never throws
 | 
			
		||||
#ifdef BOOST_SMART_PTR_CONVERSION
 | 
			
		||||
  // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
 | 
			
		||||
  operator T*() const                { return ptr; }  // never throws
 | 
			
		||||
#else 
 | 
			
		||||
  T& operator[](std::size_t i) const { return ptr[i]; }  // never throws
 | 
			
		||||
#endif
 | 
			
		||||
  };  // scoped_array
 | 
			
		||||
 | 
			
		||||
//  shared_ptr  --------------------------------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  An enhanced relative of scoped_ptr with reference counted copy semantics.
 | 
			
		||||
//  The object pointed to is deleted when the last shared_ptr pointing to it
 | 
			
		||||
//  is destroyed or reset.
 | 
			
		||||
 | 
			
		||||
template<typename T> class shared_ptr {
 | 
			
		||||
  public:
 | 
			
		||||
   typedef T element_type;
 | 
			
		||||
 | 
			
		||||
   explicit shared_ptr(T* p =0) : px(p) {
 | 
			
		||||
      try { pn = new long(1); }  // fix: prevent leak if new throws
 | 
			
		||||
      catch (...) { checked_delete(p); throw; } 
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   shared_ptr(const shared_ptr& r) : px(r.px) { ++*(pn = r.pn); }  // never throws
 | 
			
		||||
 | 
			
		||||
   ~shared_ptr() { dispose(); }
 | 
			
		||||
 | 
			
		||||
   shared_ptr& operator=(const shared_ptr& r) {
 | 
			
		||||
      share(r.px,r.pn);
 | 
			
		||||
      return *this;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_MEMBER_TEMPLATES )
 | 
			
		||||
   template<typename Y>
 | 
			
		||||
      shared_ptr(const shared_ptr<Y>& r) : px(r.px) {  // never throws 
 | 
			
		||||
         ++*(pn = r.pn); 
 | 
			
		||||
      }
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
   template<typename Y>
 | 
			
		||||
      explicit shared_ptr(std::auto_ptr<Y>& r) { 
 | 
			
		||||
         pn = new long(1); // may throw
 | 
			
		||||
         px = r.release(); // fix: moved here to stop leak if new throws
 | 
			
		||||
      }
 | 
			
		||||
#endif 
 | 
			
		||||
 | 
			
		||||
   template<typename Y>
 | 
			
		||||
      shared_ptr& operator=(const shared_ptr<Y>& r) { 
 | 
			
		||||
         share(r.px,r.pn);
 | 
			
		||||
         return *this;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
   template<typename Y>
 | 
			
		||||
      shared_ptr& operator=(std::auto_ptr<Y>& r) {
 | 
			
		||||
         // code choice driven by guarantee of "no effect if new throws"
 | 
			
		||||
         if (*pn == 1) { checked_delete(px); }
 | 
			
		||||
         else { // allocate new reference counter
 | 
			
		||||
           long * tmp = new long(1); // may throw
 | 
			
		||||
           --*pn; // only decrement once danger of new throwing is past
 | 
			
		||||
           pn = tmp;
 | 
			
		||||
         } // allocate new reference counter
 | 
			
		||||
         px = r.release(); // fix: moved here so doesn't leak if new throws 
 | 
			
		||||
         return *this;
 | 
			
		||||
      }
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
      explicit shared_ptr(std::auto_ptr<T>& r) { 
 | 
			
		||||
         pn = new long(1); // may throw
 | 
			
		||||
         px = r.release(); // fix: moved here to stop leak if new throws
 | 
			
		||||
      } 
 | 
			
		||||
 | 
			
		||||
      shared_ptr& operator=(std::auto_ptr<T>& r) {
 | 
			
		||||
         // code choice driven by guarantee of "no effect if new throws"
 | 
			
		||||
         if (*pn == 1) { checked_delete(px); }
 | 
			
		||||
         else { // allocate new reference counter
 | 
			
		||||
           long * tmp = new long(1); // may throw
 | 
			
		||||
           --*pn; // only decrement once danger of new throwing is past
 | 
			
		||||
           pn = tmp;
 | 
			
		||||
         } // allocate new reference counter
 | 
			
		||||
         px = r.release(); // fix: moved here so doesn't leak if new throws 
 | 
			
		||||
         return *this;
 | 
			
		||||
      }
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   void reset(T* p=0) {
 | 
			
		||||
      if ( px == p ) return;  // fix: self-assignment safe
 | 
			
		||||
      if (--*pn == 0) { checked_delete(px); }
 | 
			
		||||
      else { // allocate new reference counter
 | 
			
		||||
        try { pn = new long; }  // fix: prevent leak if new throws
 | 
			
		||||
        catch (...) {
 | 
			
		||||
          ++*pn;  // undo effect of --*pn above to meet effects guarantee 
 | 
			
		||||
          checked_delete(p);
 | 
			
		||||
          throw;
 | 
			
		||||
        } // catch
 | 
			
		||||
      } // allocate new reference counter
 | 
			
		||||
      *pn = 1;
 | 
			
		||||
      px = p;
 | 
			
		||||
   } // reset
 | 
			
		||||
 | 
			
		||||
   T& operator*() const          { return *px; }  // never throws
 | 
			
		||||
   T* operator->() const         { return px; }  // never throws
 | 
			
		||||
   T* get() const                { return px; }  // never throws
 | 
			
		||||
 #ifdef BOOST_SMART_PTR_CONVERSION
 | 
			
		||||
   // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
 | 
			
		||||
   operator T*() const           { return px; }  // never throws 
 | 
			
		||||
 #endif
 | 
			
		||||
 | 
			
		||||
   long use_count() const        { return *pn; }  // never throws
 | 
			
		||||
   bool unique() const           { return *pn == 1; }  // never throws
 | 
			
		||||
 | 
			
		||||
   void swap(shared_ptr<T>& other)  // never throws
 | 
			
		||||
     { std::swap(px,other.px); std::swap(pn,other.pn); }
 | 
			
		||||
 | 
			
		||||
// Tasteless as this may seem, making all members public allows member templates
 | 
			
		||||
// to work in the absence of member template friends. (Matthew Langston)
 | 
			
		||||
// Don't split this line into two; that causes problems for some GCC 2.95.2 builds
 | 
			
		||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) || !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
 | 
			
		||||
   private:
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   T*     px;     // contained pointer
 | 
			
		||||
   long*  pn;     // ptr to reference counter
 | 
			
		||||
 | 
			
		||||
// Don't split this line into two; that causes problems for some GCC 2.95.2 builds
 | 
			
		||||
#if !defined( BOOST_NO_MEMBER_TEMPLATES ) && !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
 | 
			
		||||
   template<typename Y> friend class shared_ptr;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   void dispose() { if (--*pn == 0) { checked_delete(px); delete pn; } }
 | 
			
		||||
 | 
			
		||||
   void share(T* rpx, long* rpn) {
 | 
			
		||||
      if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0
 | 
			
		||||
         ++*rpn; // done before dispose() in case rpn transitively
 | 
			
		||||
                 // dependent on *this (bug reported by Ken Johnson)
 | 
			
		||||
         dispose();
 | 
			
		||||
         px = rpx;
 | 
			
		||||
         pn = rpn;
 | 
			
		||||
      }
 | 
			
		||||
   } // share
 | 
			
		||||
};  // shared_ptr
 | 
			
		||||
 | 
			
		||||
template<typename T, typename U>
 | 
			
		||||
  inline bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b)
 | 
			
		||||
    { return a.get() == b.get(); }
 | 
			
		||||
 | 
			
		||||
template<typename T, typename U>
 | 
			
		||||
  inline bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b)
 | 
			
		||||
    { return a.get() != b.get(); }
 | 
			
		||||
 | 
			
		||||
//  shared_array  ------------------------------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  shared_array extends shared_ptr to arrays.
 | 
			
		||||
//  The array pointed to is deleted when the last shared_array pointing to it
 | 
			
		||||
//  is destroyed or reset.
 | 
			
		||||
 | 
			
		||||
template<typename T> class shared_array {
 | 
			
		||||
  public:
 | 
			
		||||
   typedef T element_type;
 | 
			
		||||
 | 
			
		||||
   explicit shared_array(T* p =0) : px(p) {
 | 
			
		||||
      try { pn = new long(1); }  // fix: prevent leak if new throws
 | 
			
		||||
      catch (...) { checked_array_delete(p); throw; } 
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   shared_array(const shared_array& r) : px(r.px)  // never throws
 | 
			
		||||
      { ++*(pn = r.pn); }
 | 
			
		||||
 | 
			
		||||
   ~shared_array() { dispose(); }
 | 
			
		||||
 | 
			
		||||
   shared_array& operator=(const shared_array& r) {
 | 
			
		||||
      if (pn != r.pn) { // Q: why not px != r.px? A: fails when both px == 0
 | 
			
		||||
         ++*r.pn; // done before dispose() in case r.pn transitively
 | 
			
		||||
                  // dependent on *this (bug reported by Ken Johnson)
 | 
			
		||||
         dispose();
 | 
			
		||||
         px = r.px;
 | 
			
		||||
         pn = r.pn;
 | 
			
		||||
      }
 | 
			
		||||
      return *this;
 | 
			
		||||
   } // operator=
 | 
			
		||||
 | 
			
		||||
   void reset(T* p=0) {
 | 
			
		||||
      if ( px == p ) return;  // fix: self-assignment safe
 | 
			
		||||
      if (--*pn == 0) { checked_array_delete(px); }
 | 
			
		||||
      else { // allocate new reference counter
 | 
			
		||||
        try { pn = new long; }  // fix: prevent leak if new throws
 | 
			
		||||
        catch (...) {
 | 
			
		||||
          ++*pn;  // undo effect of --*pn above to meet effects guarantee 
 | 
			
		||||
          checked_array_delete(p);
 | 
			
		||||
          throw;
 | 
			
		||||
        } // catch
 | 
			
		||||
      } // allocate new reference counter
 | 
			
		||||
      *pn = 1;
 | 
			
		||||
      px = p;
 | 
			
		||||
   } // reset
 | 
			
		||||
 | 
			
		||||
   T* get() const                     { return px; }  // never throws
 | 
			
		||||
 #ifdef BOOST_SMART_PTR_CONVERSION
 | 
			
		||||
   // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
 | 
			
		||||
   operator T*() const                { return px; }  // never throws
 | 
			
		||||
 #else 
 | 
			
		||||
   T& operator[](std::size_t i) const { return px[i]; }  // never throws
 | 
			
		||||
 #endif
 | 
			
		||||
 | 
			
		||||
   long use_count() const             { return *pn; }  // never throws
 | 
			
		||||
   bool unique() const                { return *pn == 1; }  // never throws
 | 
			
		||||
 | 
			
		||||
   void swap(shared_array<T>& other)  // never throws
 | 
			
		||||
     { std::swap(px,other.px); std::swap(pn,other.pn); }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
   T*     px;     // contained pointer
 | 
			
		||||
   long*  pn;     // ptr to reference counter
 | 
			
		||||
 | 
			
		||||
   void dispose() { if (--*pn == 0) { checked_array_delete(px); delete pn; } }
 | 
			
		||||
 | 
			
		||||
};  // shared_array
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
  inline bool operator==(const shared_array<T>& a, const shared_array<T>& b)
 | 
			
		||||
    { return a.get() == b.get(); }
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
  inline bool operator!=(const shared_array<T>& a, const shared_array<T>& b)
 | 
			
		||||
    { return a.get() != b.get(); }
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
//  specializations for things in namespace std  -----------------------------//
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
namespace std {
 | 
			
		||||
 | 
			
		||||
// Specialize std::swap to use the fast, non-throwing swap that's provided
 | 
			
		||||
// as a member function instead of using the default algorithm which creates
 | 
			
		||||
// a temporary and uses assignment.
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
  inline void swap(boost::shared_ptr<T>& a, boost::shared_ptr<T>& b)
 | 
			
		||||
    { a.swap(b); }
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
  inline void swap(boost::shared_array<T>& a, boost::shared_array<T>& b)
 | 
			
		||||
    { a.swap(b); }
 | 
			
		||||
 | 
			
		||||
// Specialize std::less so we can use shared pointers and arrays as keys in
 | 
			
		||||
// associative collections.
 | 
			
		||||
 | 
			
		||||
// It's still a controversial question whether this is better than supplying
 | 
			
		||||
// a full range of comparison operators (<, >, <=, >=).
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
  struct less< boost::shared_ptr<T> >
 | 
			
		||||
    : binary_function<boost::shared_ptr<T>, boost::shared_ptr<T>, bool>
 | 
			
		||||
  {
 | 
			
		||||
    bool operator()(const boost::shared_ptr<T>& a,
 | 
			
		||||
        const boost::shared_ptr<T>& b) const
 | 
			
		||||
      { return less<T*>()(a.get(),b.get()); }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
  struct less< boost::shared_array<T> >
 | 
			
		||||
    : binary_function<boost::shared_array<T>, boost::shared_array<T>, bool>
 | 
			
		||||
  {
 | 
			
		||||
    bool operator()(const boost::shared_array<T>& a,
 | 
			
		||||
        const boost::shared_array<T>& b) const
 | 
			
		||||
      { return less<T*>()(a.get(),b.get()); }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
} // namespace std
 | 
			
		||||
 | 
			
		||||
#endif  // ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif    
 | 
			
		||||
 | 
			
		||||
#endif  // BOOST_SMART_PTR_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/scoped_ptr.hpp>
 | 
			
		||||
#include <boost/scoped_array.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/shared_array.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
#include <boost/intrusive_ptr.hpp>
 | 
			
		||||
#include <boost/enable_shared_from_this.hpp>
 | 
			
		||||
#include <boost/make_shared.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -1,228 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2017 Glen Joseph Fernandes
 | 
			
		||||
(glenjofe@gmail.com)
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
(http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
*/
 | 
			
		||||
#ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
 | 
			
		||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
template<class>
 | 
			
		||||
struct lsp_if_array { };
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct lsp_if_array<T[]> {
 | 
			
		||||
    typedef boost::local_shared_ptr<T[]> type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class>
 | 
			
		||||
struct lsp_if_size_array { };
 | 
			
		||||
 | 
			
		||||
template<class T, std::size_t N>
 | 
			
		||||
struct lsp_if_size_array<T[N]> {
 | 
			
		||||
    typedef boost::local_shared_ptr<T[N]> type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE lsp_array_base
 | 
			
		||||
    : public local_counted_base {
 | 
			
		||||
public:
 | 
			
		||||
    void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
 | 
			
		||||
        count_ = shared_count(base);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        shared_count().swap(count_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    shared_count count_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class A>
 | 
			
		||||
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
 | 
			
		||||
        : sp_array_state<A>(other, size) { }
 | 
			
		||||
 | 
			
		||||
    lsp_array_base& base() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return base_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    lsp_array_base base_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class A, std::size_t N>
 | 
			
		||||
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
 | 
			
		||||
        : sp_size_array_state<A, N>(other, size) { }
 | 
			
		||||
 | 
			
		||||
    lsp_array_base& base() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return base_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    lsp_array_base base_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} /* detail */
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::lsp_if_array<T>::type
 | 
			
		||||
allocate_local_shared(const A& allocator, std::size_t count)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::lsp_array_state<other> state;
 | 
			
		||||
    typedef detail::sp_array_base<state> base;
 | 
			
		||||
    std::size_t size = count * detail::sp_array_count<type>::value;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(allocator, size, start);
 | 
			
		||||
    detail::lsp_array_base& local = node->state().base();
 | 
			
		||||
    local.set(node);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), &local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::lsp_if_size_array<T>::type
 | 
			
		||||
allocate_local_shared(const A& allocator)
 | 
			
		||||
{
 | 
			
		||||
    enum {
 | 
			
		||||
        size = detail::sp_array_count<T>::value
 | 
			
		||||
    };
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::lsp_size_array_state<other, size> state;
 | 
			
		||||
    typedef detail::sp_array_base<state> base;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(allocator, size, start);
 | 
			
		||||
    detail::lsp_array_base& local = node->state().base();
 | 
			
		||||
    local.set(node);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), &local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::lsp_if_array<T>::type
 | 
			
		||||
allocate_local_shared(const A& allocator, std::size_t count,
 | 
			
		||||
    const typename detail::sp_array_element<T>::type& value)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::lsp_array_state<other> state;
 | 
			
		||||
    typedef detail::sp_array_base<state> base;
 | 
			
		||||
    std::size_t size = count * detail::sp_array_count<type>::value;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(allocator, size,
 | 
			
		||||
        reinterpret_cast<const scalar*>(&value),
 | 
			
		||||
        detail::sp_array_count<type>::value, start);
 | 
			
		||||
    detail::lsp_array_base& local = node->state().base();
 | 
			
		||||
    local.set(node);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), &local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::lsp_if_size_array<T>::type
 | 
			
		||||
allocate_local_shared(const A& allocator,
 | 
			
		||||
    const typename detail::sp_array_element<T>::type& value)
 | 
			
		||||
{
 | 
			
		||||
    enum {
 | 
			
		||||
        size = detail::sp_array_count<T>::value
 | 
			
		||||
    };
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::lsp_size_array_state<other, size> state;
 | 
			
		||||
    typedef detail::sp_array_base<state> base;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(allocator, size,
 | 
			
		||||
        reinterpret_cast<const scalar*>(&value),
 | 
			
		||||
        detail::sp_array_count<type>::value, start);
 | 
			
		||||
    detail::lsp_array_base& local = node->state().base();
 | 
			
		||||
    local.set(node);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), &local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::lsp_if_array<T>::type
 | 
			
		||||
allocate_local_shared_noinit(const A& allocator, std::size_t count)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::lsp_array_state<other> state;
 | 
			
		||||
    typedef detail::sp_array_base<state, false> base;
 | 
			
		||||
    std::size_t size = count * detail::sp_array_count<type>::value;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
 | 
			
		||||
        size, start);
 | 
			
		||||
    detail::lsp_array_base& local = node->state().base();
 | 
			
		||||
    local.set(node);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), &local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::lsp_if_size_array<T>::type
 | 
			
		||||
allocate_local_shared_noinit(const A& allocator)
 | 
			
		||||
{
 | 
			
		||||
    enum {
 | 
			
		||||
        size = detail::sp_array_count<T>::value
 | 
			
		||||
    };
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::lsp_size_array_state<other, size> state;
 | 
			
		||||
    typedef detail::sp_array_base<state, false> base;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
 | 
			
		||||
        size, start);
 | 
			
		||||
    detail::lsp_array_base& local = node->state().base();
 | 
			
		||||
    local.set(node);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), &local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} /* boost */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,648 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2012-2018 Glen Joseph Fernandes
 | 
			
		||||
(glenjofe@gmail.com)
 | 
			
		||||
 | 
			
		||||
Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
(http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
*/
 | 
			
		||||
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
#include <boost/type_traits/alignment_of.hpp>
 | 
			
		||||
#include <boost/type_traits/has_trivial_assign.hpp>
 | 
			
		||||
#include <boost/type_traits/has_trivial_constructor.hpp>
 | 
			
		||||
#include <boost/type_traits/has_trivial_destructor.hpp>
 | 
			
		||||
#include <boost/type_traits/type_with_alignment.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
template<class>
 | 
			
		||||
struct sp_if_array { };
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_if_array<T[]> {
 | 
			
		||||
    typedef boost::shared_ptr<T[]> type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class>
 | 
			
		||||
struct sp_if_size_array { };
 | 
			
		||||
 | 
			
		||||
template<class T, std::size_t N>
 | 
			
		||||
struct sp_if_size_array<T[N]> {
 | 
			
		||||
    typedef boost::shared_ptr<T[N]> type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class>
 | 
			
		||||
struct sp_array_element { };
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_array_element<T[]> {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, std::size_t N>
 | 
			
		||||
struct sp_array_element<T[N]> {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_array_scalar {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, std::size_t N>
 | 
			
		||||
struct sp_array_scalar<T[N]> {
 | 
			
		||||
    typedef typename sp_array_scalar<T>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, std::size_t N>
 | 
			
		||||
struct sp_array_scalar<const T[N]> {
 | 
			
		||||
    typedef typename sp_array_scalar<T>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, std::size_t N>
 | 
			
		||||
struct sp_array_scalar<volatile T[N]> {
 | 
			
		||||
    typedef typename sp_array_scalar<T>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, std::size_t N>
 | 
			
		||||
struct sp_array_scalar<const volatile T[N]> {
 | 
			
		||||
    typedef typename sp_array_scalar<T>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_array_scalar<T[]> {
 | 
			
		||||
    typedef typename sp_array_scalar<T>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_array_scalar<const T[]> {
 | 
			
		||||
    typedef typename sp_array_scalar<T>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_array_scalar<volatile T[]> {
 | 
			
		||||
    typedef typename sp_array_scalar<T>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_array_scalar<const volatile T[]> {
 | 
			
		||||
    typedef typename sp_array_scalar<T>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_array_count {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = 1
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, std::size_t N>
 | 
			
		||||
struct sp_array_count<T[N]> {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = N * sp_array_count<T>::value
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<std::size_t N, std::size_t M>
 | 
			
		||||
struct sp_max_size {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = N < M ? M : N
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<std::size_t N, std::size_t M>
 | 
			
		||||
struct sp_align_up {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = (N + M - 1) & ~(M - 1)
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
{
 | 
			
		||||
    return (size + sizeof(T) - 1) / sizeof(T);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<bool, class = void>
 | 
			
		||||
struct sp_enable { };
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_enable<true, T> {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<!E && boost::has_trivial_destructor<T>::value>::type
 | 
			
		||||
sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
 | 
			
		||||
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<!E &&
 | 
			
		||||
    !boost::has_trivial_destructor<T>::value>::type
 | 
			
		||||
sp_array_destroy(A&, T* ptr, std::size_t size)
 | 
			
		||||
{
 | 
			
		||||
    while (size > 0) {
 | 
			
		||||
        ptr[--size].~T();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<E>::type
 | 
			
		||||
sp_array_destroy(A& allocator, T* ptr, std::size_t size)
 | 
			
		||||
{
 | 
			
		||||
    while (size > 0) {
 | 
			
		||||
        std::allocator_traits<A>::destroy(allocator, ptr + --size);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
class sp_destroyer {
 | 
			
		||||
public:
 | 
			
		||||
    sp_destroyer(A& allocator, T* ptr) BOOST_SP_NOEXCEPT
 | 
			
		||||
        : allocator_(allocator),
 | 
			
		||||
          ptr_(ptr),
 | 
			
		||||
          size_(0) { }
 | 
			
		||||
 | 
			
		||||
    ~sp_destroyer() {
 | 
			
		||||
        sp_array_destroy<E>(allocator_, ptr_, size_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::size_t& size() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return size_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    sp_destroyer(const sp_destroyer&);
 | 
			
		||||
    sp_destroyer& operator=(const sp_destroyer&);
 | 
			
		||||
 | 
			
		||||
    A& allocator_;
 | 
			
		||||
    T* ptr_;
 | 
			
		||||
    std::size_t size_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<!E &&
 | 
			
		||||
    boost::has_trivial_constructor<T>::value &&
 | 
			
		||||
    boost::has_trivial_assign<T>::value &&
 | 
			
		||||
    boost::has_trivial_destructor<T>::value>::type
 | 
			
		||||
sp_array_construct(A&, T* ptr, std::size_t size)
 | 
			
		||||
{
 | 
			
		||||
    for (std::size_t i = 0; i < size; ++i) {
 | 
			
		||||
        ptr[i] = T();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<!E &&
 | 
			
		||||
    boost::has_trivial_constructor<T>::value &&
 | 
			
		||||
    boost::has_trivial_assign<T>::value &&
 | 
			
		||||
    boost::has_trivial_destructor<T>::value>::type
 | 
			
		||||
sp_array_construct(A&, T* ptr, std::size_t size, const T* list,
 | 
			
		||||
    std::size_t count)
 | 
			
		||||
{
 | 
			
		||||
    for (std::size_t i = 0; i < size; ++i) {
 | 
			
		||||
        ptr[i] = list[i % count];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<!E &&
 | 
			
		||||
    !(boost::has_trivial_constructor<T>::value &&
 | 
			
		||||
      boost::has_trivial_assign<T>::value &&
 | 
			
		||||
      boost::has_trivial_destructor<T>::value)>::type
 | 
			
		||||
sp_array_construct(A& none, T* ptr, std::size_t size)
 | 
			
		||||
{
 | 
			
		||||
    sp_destroyer<E, A, T> hold(none, ptr);
 | 
			
		||||
    for (std::size_t& i = hold.size(); i < size; ++i) {
 | 
			
		||||
        ::new(static_cast<void*>(ptr + i)) T();
 | 
			
		||||
    }
 | 
			
		||||
    hold.size() = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<!E &&
 | 
			
		||||
    !(boost::has_trivial_constructor<T>::value &&
 | 
			
		||||
      boost::has_trivial_assign<T>::value &&
 | 
			
		||||
      boost::has_trivial_destructor<T>::value)>::type
 | 
			
		||||
sp_array_construct(A& none, T* ptr, std::size_t size, const T* list,
 | 
			
		||||
    std::size_t count)
 | 
			
		||||
{
 | 
			
		||||
    sp_destroyer<E, A, T> hold(none, ptr);
 | 
			
		||||
    for (std::size_t& i = hold.size(); i < size; ++i) {
 | 
			
		||||
        ::new(static_cast<void*>(ptr + i)) T(list[i % count]);
 | 
			
		||||
    }
 | 
			
		||||
    hold.size() = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<E>::type
 | 
			
		||||
sp_array_construct(A& allocator, T* ptr, std::size_t size)
 | 
			
		||||
{
 | 
			
		||||
    sp_destroyer<E, A, T> hold(allocator, ptr);
 | 
			
		||||
    for (std::size_t& i = hold.size(); i < size; ++i) {
 | 
			
		||||
        std::allocator_traits<A>::construct(allocator, ptr + i);
 | 
			
		||||
    }
 | 
			
		||||
    hold.size() = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<bool E, class A, class T>
 | 
			
		||||
inline typename sp_enable<E>::type
 | 
			
		||||
sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
 | 
			
		||||
    std::size_t count)
 | 
			
		||||
{
 | 
			
		||||
    sp_destroyer<E, A, T> hold(allocator, ptr);
 | 
			
		||||
    for (std::size_t& i = hold.size(); i < size; ++i) {
 | 
			
		||||
        std::allocator_traits<A>::construct(allocator, ptr + i,
 | 
			
		||||
            list[i % count]);
 | 
			
		||||
    }
 | 
			
		||||
    hold.size() = 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class A, class T>
 | 
			
		||||
inline typename sp_enable<boost::has_trivial_constructor<T>::value>::type
 | 
			
		||||
sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
 | 
			
		||||
 | 
			
		||||
template<class A, class T>
 | 
			
		||||
inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type
 | 
			
		||||
sp_array_default(A& none, T* ptr, std::size_t size)
 | 
			
		||||
{
 | 
			
		||||
    sp_destroyer<false, A, T> hold(none, ptr);
 | 
			
		||||
    for (std::size_t& i = hold.size(); i < size; ++i) {
 | 
			
		||||
        ::new(static_cast<void*>(ptr + i)) T;
 | 
			
		||||
    }
 | 
			
		||||
    hold.size() = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class A>
 | 
			
		||||
class sp_array_state {
 | 
			
		||||
public:
 | 
			
		||||
    typedef A type;
 | 
			
		||||
 | 
			
		||||
    template<class U>
 | 
			
		||||
    sp_array_state(const U& _allocator, std::size_t _size) BOOST_SP_NOEXCEPT
 | 
			
		||||
        : allocator_(_allocator),
 | 
			
		||||
          size_(_size) { }
 | 
			
		||||
 | 
			
		||||
    A& allocator() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return allocator_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::size_t size() const BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return size_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    A allocator_;
 | 
			
		||||
    std::size_t size_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class A, std::size_t N>
 | 
			
		||||
class sp_size_array_state {
 | 
			
		||||
public:
 | 
			
		||||
    typedef A type;
 | 
			
		||||
 | 
			
		||||
    template<class U>
 | 
			
		||||
    sp_size_array_state(const U& _allocator, std::size_t) BOOST_SP_NOEXCEPT
 | 
			
		||||
        : allocator_(_allocator) { }
 | 
			
		||||
 | 
			
		||||
    A& allocator() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return allocator_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_CONSTEXPR std::size_t size() const BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return N;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    A allocator_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
template<class A>
 | 
			
		||||
struct sp_use_construct {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = true
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct sp_use_construct<std::allocator<T> > {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = false
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
#else
 | 
			
		||||
template<class>
 | 
			
		||||
struct sp_use_construct {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = false
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
struct sp_array_alignment {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = sp_max_size<boost::alignment_of<T>::value,
 | 
			
		||||
            boost::alignment_of<U>::value>::value
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
struct sp_array_offset {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = sp_align_up<sizeof(T), sp_array_alignment<T, U>::value>::value
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
struct sp_array_storage {
 | 
			
		||||
    enum {
 | 
			
		||||
        value = sp_array_alignment<T, U>::value
 | 
			
		||||
    };
 | 
			
		||||
    typedef typename boost::type_with_alignment<value>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
inline U*
 | 
			
		||||
sp_array_start(void* base) BOOST_SP_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    enum {
 | 
			
		||||
        size = sp_array_offset<T, U>::value
 | 
			
		||||
    };
 | 
			
		||||
    return reinterpret_cast<U*>(static_cast<char*>(base) + size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class A, class T>
 | 
			
		||||
class sp_array_creator {
 | 
			
		||||
    typedef typename A::value_type scalar;
 | 
			
		||||
 | 
			
		||||
    enum {
 | 
			
		||||
        offset = sp_array_offset<T, scalar>::value
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef typename sp_array_storage<T, scalar>::type type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    template<class U>
 | 
			
		||||
    sp_array_creator(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
 | 
			
		||||
        : other_(other),
 | 
			
		||||
          size_(sp_objects<type>(offset + sizeof(scalar) * size)) { }
 | 
			
		||||
 | 
			
		||||
    T* create() {
 | 
			
		||||
        return reinterpret_cast<T*>(other_.allocate(size_));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void destroy(T* base) {
 | 
			
		||||
        other_.deallocate(reinterpret_cast<type*>(base), size_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    typename sp_bind_allocator<A, type>::type other_;
 | 
			
		||||
    std::size_t size_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sp_default { };
 | 
			
		||||
 | 
			
		||||
template<class T, bool E = sp_use_construct<T>::value>
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE sp_array_base
 | 
			
		||||
    : public sp_counted_base {
 | 
			
		||||
    typedef typename T::type allocator;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    typedef typename allocator::value_type type;
 | 
			
		||||
 | 
			
		||||
    template<class A>
 | 
			
		||||
    sp_array_base(const A& other, std::size_t size, type* start)
 | 
			
		||||
        : state_(other, size) {
 | 
			
		||||
        sp_array_construct<E>(state_.allocator(), start, state_.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class A>
 | 
			
		||||
    sp_array_base(const A& other, std::size_t size, const type* list,
 | 
			
		||||
        std::size_t count, type* start)
 | 
			
		||||
        : state_(other, size) {
 | 
			
		||||
        sp_array_construct<E>(state_.allocator(), start, state_.size(), list,
 | 
			
		||||
            count);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class A>
 | 
			
		||||
    sp_array_base(sp_default, const A& other, std::size_t size, type* start)
 | 
			
		||||
        : state_(other, size) {
 | 
			
		||||
        sp_array_default(state_.allocator(), start, state_.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T& state() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return state_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        sp_array_destroy<E>(state_.allocator(),
 | 
			
		||||
            sp_array_start<sp_array_base, type>(this), state_.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        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 {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void* get_local_deleter(const sp_typeinfo&) BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void* get_untyped_deleter() BOOST_SP_NOEXCEPT {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    T state_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class A, class T>
 | 
			
		||||
struct sp_array_result {
 | 
			
		||||
public:
 | 
			
		||||
    template<class U>
 | 
			
		||||
    sp_array_result(const U& other, std::size_t size)
 | 
			
		||||
        : creator_(other, size),
 | 
			
		||||
          result_(creator_.create()) { }
 | 
			
		||||
 | 
			
		||||
    ~sp_array_result() {
 | 
			
		||||
        if (result_) {
 | 
			
		||||
            creator_.destroy(result_);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T* get() const {
 | 
			
		||||
        return result_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() {
 | 
			
		||||
        result_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    sp_array_result(const sp_array_result&);
 | 
			
		||||
    sp_array_result& operator=(const sp_array_result&);
 | 
			
		||||
 | 
			
		||||
    sp_array_creator<A, T> creator_;
 | 
			
		||||
    T* result_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} /* detail */
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::sp_if_array<T>::type
 | 
			
		||||
allocate_shared(const A& allocator, std::size_t count)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::sp_array_state<other> state;
 | 
			
		||||
    typedef detail::sp_array_base<state> base;
 | 
			
		||||
    std::size_t size = count * detail::sp_array_count<type>::value;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    detail::sp_counted_base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(allocator, size, start);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return shared_ptr<T>(detail::sp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), detail::shared_count(node));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::sp_if_size_array<T>::type
 | 
			
		||||
allocate_shared(const A& allocator)
 | 
			
		||||
{
 | 
			
		||||
    enum {
 | 
			
		||||
        size = detail::sp_array_count<T>::value
 | 
			
		||||
    };
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::sp_size_array_state<other, size> state;
 | 
			
		||||
    typedef detail::sp_array_base<state> base;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    detail::sp_counted_base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(allocator, size, start);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return shared_ptr<T>(detail::sp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), detail::shared_count(node));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::sp_if_array<T>::type
 | 
			
		||||
allocate_shared(const A& allocator, std::size_t count,
 | 
			
		||||
    const typename detail::sp_array_element<T>::type& value)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::sp_array_state<other> state;
 | 
			
		||||
    typedef detail::sp_array_base<state> base;
 | 
			
		||||
    std::size_t size = count * detail::sp_array_count<type>::value;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    detail::sp_counted_base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(allocator, size,
 | 
			
		||||
        reinterpret_cast<const scalar*>(&value),
 | 
			
		||||
        detail::sp_array_count<type>::value, start);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return shared_ptr<T>(detail::sp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), detail::shared_count(node));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::sp_if_size_array<T>::type
 | 
			
		||||
allocate_shared(const A& allocator,
 | 
			
		||||
    const typename detail::sp_array_element<T>::type& value)
 | 
			
		||||
{
 | 
			
		||||
    enum {
 | 
			
		||||
        size = detail::sp_array_count<T>::value
 | 
			
		||||
    };
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::sp_size_array_state<other, size> state;
 | 
			
		||||
    typedef detail::sp_array_base<state> base;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    detail::sp_counted_base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(allocator, size,
 | 
			
		||||
        reinterpret_cast<const scalar*>(&value),
 | 
			
		||||
        detail::sp_array_count<type>::value, start);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return shared_ptr<T>(detail::sp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), detail::shared_count(node));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::sp_if_array<T>::type
 | 
			
		||||
allocate_shared_noinit(const A& allocator, std::size_t count)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::sp_array_state<other> state;
 | 
			
		||||
    typedef detail::sp_array_base<state, false> base;
 | 
			
		||||
    std::size_t size = count * detail::sp_array_count<type>::value;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    detail::sp_counted_base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
 | 
			
		||||
        size, start);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return shared_ptr<T>(detail::sp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), detail::shared_count(node));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
inline typename detail::sp_if_size_array<T>::type
 | 
			
		||||
allocate_shared_noinit(const A& allocator)
 | 
			
		||||
{
 | 
			
		||||
    enum {
 | 
			
		||||
        size = detail::sp_array_count<T>::value
 | 
			
		||||
    };
 | 
			
		||||
    typedef typename detail::sp_array_element<T>::type type;
 | 
			
		||||
    typedef typename detail::sp_array_scalar<T>::type scalar;
 | 
			
		||||
    typedef typename detail::sp_bind_allocator<A, scalar>::type other;
 | 
			
		||||
    typedef detail::sp_size_array_state<other, size> state;
 | 
			
		||||
    typedef detail::sp_array_base<state, false> base;
 | 
			
		||||
    detail::sp_array_result<other, base> result(allocator, size);
 | 
			
		||||
    detail::sp_counted_base* node = result.get();
 | 
			
		||||
    scalar* start = detail::sp_array_start<base, scalar>(node);
 | 
			
		||||
    ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
 | 
			
		||||
        size, start);
 | 
			
		||||
    result.release();
 | 
			
		||||
    return shared_ptr<T>(detail::sp_internal_constructor_tag(),
 | 
			
		||||
        reinterpret_cast<type*>(start), detail::shared_count(node));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} /* boost */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,233 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  atomic_shared_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2017 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/spinlock.hpp>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class atomic_shared_ptr
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    boost::shared_ptr<T> p_;
 | 
			
		||||
 | 
			
		||||
    mutable boost::detail::spinlock l_;
 | 
			
		||||
 | 
			
		||||
    atomic_shared_ptr(const atomic_shared_ptr&);
 | 
			
		||||
    atomic_shared_ptr& operator=(const atomic_shared_ptr&);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        l_.lock();
 | 
			
		||||
 | 
			
		||||
        if( p_._internal_equiv( v ) )
 | 
			
		||||
        {
 | 
			
		||||
            p_.swap( w );
 | 
			
		||||
 | 
			
		||||
            l_.unlock();
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            shared_ptr<T> tmp( p_ );
 | 
			
		||||
 | 
			
		||||
            l_.unlock();
 | 
			
		||||
 | 
			
		||||
            tmp.swap( v );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    atomic_shared_ptr() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
 | 
			
		||||
        std::memcpy( &l_, &init, sizeof( init ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
        : p_( std::move( p ) )
 | 
			
		||||
#else
 | 
			
		||||
        : p_( p )
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
 | 
			
		||||
        std::memcpy( &l_, &init, sizeof( init ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::spinlock::scoped_lock lock( l_ );
 | 
			
		||||
        p_.swap( r );
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> load() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::spinlock::scoped_lock lock( l_ );
 | 
			
		||||
        return p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::spinlock::scoped_lock lock( l_ );
 | 
			
		||||
        return p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::spinlock::scoped_lock lock( l_ );
 | 
			
		||||
        return p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::spinlock::scoped_lock lock( l_ );
 | 
			
		||||
        p_.swap( r );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class M> void store( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::spinlock::scoped_lock lock( l_ );
 | 
			
		||||
        p_.swap( r );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> exchange( shared_ptr<T> r ) BOOST_SP_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
 | 
			
		||||
    {
 | 
			
		||||
        {
 | 
			
		||||
            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
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
    {
 | 
			
		||||
        return compare_exchange( v, w );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_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
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
    {
 | 
			
		||||
        return compare_exchange( v, w );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_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
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
    {
 | 
			
		||||
        return compare_exchange( v, std::move( w ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_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
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
    {
 | 
			
		||||
        return compare_exchange( v, std::move( w ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return compare_exchange( v, std::move( w ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
@@ -1,70 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/smart_ptr/bad_weak_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <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
 | 
			
		||||
# pragma clang diagnostic ignored "-Wweak-vtables"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class bad_weak_ptr: public std::exception
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual char const * what() const BOOST_NOEXCEPT_OR_NOTHROW
 | 
			
		||||
    {
 | 
			
		||||
        return "tr1::bad_weak_ptr";
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_CLANG)
 | 
			
		||||
# 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
 | 
			
		||||
@@ -1,99 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count.hpp - thread/SMP safe reference counter
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright (c) 2013 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
//  typedef <implementation-defined> boost::detail::atomic_count;
 | 
			
		||||
//
 | 
			
		||||
//  atomic_count a(n);
 | 
			
		||||
//
 | 
			
		||||
//    (n is convertible to long)
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Constructs an atomic_count with an initial value of n
 | 
			
		||||
//
 | 
			
		||||
//  a;
 | 
			
		||||
//
 | 
			
		||||
//    Returns: (long) the current value of a
 | 
			
		||||
//    Memory Ordering: acquire
 | 
			
		||||
//
 | 
			
		||||
//  ++a;
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Atomically increments the value of a
 | 
			
		||||
//    Returns: (long) the new value of a
 | 
			
		||||
//    Memory Ordering: acquire/release
 | 
			
		||||
//
 | 
			
		||||
//  --a;
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Atomically decrements the value of a
 | 
			
		||||
//    Returns: (long) the new value of a
 | 
			
		||||
//    Memory Ordering: acquire/release
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_AC_DISABLE_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_AC_USE_STD_ATOMIC )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_AC_USE_SPINLOCK )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_AC_USE_PTHREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_DISABLE_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_STD_ATOMIC )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_SPINLOCK )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_PTHREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_HAS_SYNC )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_HAS_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
@@ -1,72 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_gcc.hpp
 | 
			
		||||
//
 | 
			
		||||
//  atomic_count for GNU libstdc++ v3
 | 
			
		||||
//
 | 
			
		||||
//  http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright (c) 2002 Lars Gullik Bjønnes <larsbj@lyx.org>
 | 
			
		||||
//  Copyright 2003-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
 | 
			
		||||
# include <ext/atomicity.h> 
 | 
			
		||||
#else 
 | 
			
		||||
# include <bits/atomicity.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if defined(__GLIBCXX__) // g++ 3.4+
 | 
			
		||||
 | 
			
		||||
using __gnu_cxx::__atomic_add;
 | 
			
		||||
using __gnu_cxx::__exchange_and_add;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ) : value_( v ) {}
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return __exchange_and_add( &value_, +1 ) + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return __exchange_and_add( &value_, -1 ) - 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return __exchange_and_add( &value_, 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    mutable _Atomic_word value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_gcc_x86.hpp
 | 
			
		||||
//
 | 
			
		||||
//  atomic_count for g++ on 486+/AMD64
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return atomic_exchange_and_add( &value_, +1 ) + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return atomic_exchange_and_add( &value_, -1 ) - 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return atomic_exchange_and_add( &value_, 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    mutable int value_;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    static int atomic_exchange_and_add( int * pw, int dv )
 | 
			
		||||
    {
 | 
			
		||||
        // int r = *pw;
 | 
			
		||||
        // *pw += dv;
 | 
			
		||||
        // return r;
 | 
			
		||||
 | 
			
		||||
        int r;
 | 
			
		||||
 | 
			
		||||
        __asm__ __volatile__
 | 
			
		||||
        (
 | 
			
		||||
            "lock\n\t"
 | 
			
		||||
            "xadd %1, %0":
 | 
			
		||||
            "+m"( *pw ), "=r"( r ): // outputs (%0, %1)
 | 
			
		||||
            "1"( dv ): // inputs (%2 == %1)
 | 
			
		||||
            "memory", "cc" // clobbers
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_nt.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Trivial atomic_count for the single-threaded case
 | 
			
		||||
//
 | 
			
		||||
//  http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2013 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ): value_( v )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return ++value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return --value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    long value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
 | 
			
		||||
@@ -1,97 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_pthreads.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  The generic pthread_mutex-based implementation sometimes leads to
 | 
			
		||||
//    inefficiencies. Example: a class with two atomic_count members
 | 
			
		||||
//    can get away with a single mutex.
 | 
			
		||||
//
 | 
			
		||||
//  Users can detect this situation by checking BOOST_AC_USE_PTHREADS.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        scoped_lock(pthread_mutex_t & m): m_(m)
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        pthread_mutex_t & m_;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count(long v): value_(v)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~atomic_count()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        scoped_lock lock(mutex_);
 | 
			
		||||
        return ++value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        scoped_lock lock(mutex_);
 | 
			
		||||
        return --value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        scoped_lock lock(mutex_);
 | 
			
		||||
        return value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    mutable pthread_mutex_t mutex_;
 | 
			
		||||
    long value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -1,62 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_spin.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2013 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ): value_( v )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_pool<0>::scoped_lock lock( &value_ );
 | 
			
		||||
        return ++value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_pool<0>::scoped_lock lock( &value_ );
 | 
			
		||||
        return --value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_pool<0>::scoped_lock lock( &value_ );
 | 
			
		||||
        return value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    long value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_std_atomic.hpp
 | 
			
		||||
//
 | 
			
		||||
//  atomic_count for std::atomic
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2013 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ): value_( v )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return value_.fetch_add( 1, std::memory_order_acq_rel ) + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return value_.fetch_sub( 1, std::memory_order_acq_rel ) - 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return value_.load( std::memory_order_acquire );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    std::atomic_int_least32_t value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
@@ -1,61 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_sync.hpp
 | 
			
		||||
//
 | 
			
		||||
//  atomic_count for g++ 4.1+
 | 
			
		||||
//
 | 
			
		||||
//  http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
 | 
			
		||||
# include <ia64intrin.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ) : value_( v ) {}
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return __sync_add_and_fetch( &value_, 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return __sync_add_and_fetch( &value_, -1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return __sync_fetch_and_add( &value_, 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    mutable long value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
 | 
			
		||||
@@ -1,63 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_win32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ): value_( v )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return BOOST_SP_INTERLOCKED_INCREMENT( &value_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return BOOST_SP_INTERLOCKED_DECREMENT( &value_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<long const volatile &>( value_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count( atomic_count const & );
 | 
			
		||||
    atomic_count & operator=( atomic_count const & );
 | 
			
		||||
 | 
			
		||||
    long value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lightweight_mutex.hpp - lightweight mutex
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  typedef <unspecified> boost::detail::lightweight_mutex;
 | 
			
		||||
//
 | 
			
		||||
//  boost::detail::lightweight_mutex is a header-only implementation of
 | 
			
		||||
//  a subset of the Mutex concept requirements:
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
 | 
			
		||||
//
 | 
			
		||||
//  It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_HAS_THREADS)
 | 
			
		||||
#  include <boost/smart_ptr/detail/lwm_nop.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
#  include <boost/smart_ptr/detail/lwm_pthreads.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
 | 
			
		||||
#  include <boost/smart_ptr/detail/lwm_win32_cs.hpp>
 | 
			
		||||
#else
 | 
			
		||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
 | 
			
		||||
#  error Unrecognized threading platform
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
@@ -1,148 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/local_counted_base.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2017 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE local_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    local_counted_base & operator= ( local_counted_base const & );
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // not 'int' or 'unsigned' to avoid aliasing and enable optimizations
 | 
			
		||||
    enum count_type { min_ = 0, initial_ = 1, max_ = 2147483647 };
 | 
			
		||||
 | 
			
		||||
    count_type local_use_count_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    BOOST_CONSTEXPR local_counted_base() BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_CONSTEXPR local_counted_base( local_counted_base const & ) BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~local_counted_base() /*BOOST_SP_NOEXCEPT*/
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0;
 | 
			
		||||
 | 
			
		||||
    virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
#if !defined(__NVCC__)
 | 
			
		||||
#if defined( __has_builtin )
 | 
			
		||||
# if __has_builtin( __builtin_assume )
 | 
			
		||||
 | 
			
		||||
        __builtin_assume( local_use_count_ >= 1 );
 | 
			
		||||
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        local_use_count_ = static_cast<count_type>( local_use_count_ + 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        local_use_count_ = static_cast<count_type>( local_use_count_ - 1 );
 | 
			
		||||
 | 
			
		||||
        if( local_use_count_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            local_cb_destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long local_use_count() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return local_use_count_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE local_counted_impl: public local_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    local_counted_impl( local_counted_impl const & );
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    shared_count pn_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit local_counted_impl( shared_count const& pn ) BOOST_SP_NOEXCEPT: pn_( pn )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
    explicit local_counted_impl( shared_count && pn ) BOOST_SP_NOEXCEPT: pn_( std::move(pn) )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pn_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE local_counted_impl_em: public local_counted_base
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    shared_count pn_;
 | 
			
		||||
 | 
			
		||||
    virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        shared_count().swap( pn_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pn_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
@@ -1,91 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/local_sp_deleter.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2017 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/local_counted_base.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class D> class local_sp_deleter: public local_counted_impl_em
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    D d_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    local_sp_deleter(): d_()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    explicit local_sp_deleter( D const& d ) BOOST_SP_NOEXCEPT: d_( d )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
    explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    D& deleter() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return d_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> void operator()( Y* p ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        d_( p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
    void operator()( boost::detail::sp_nullptr_t p ) BOOST_SP_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
 | 
			
		||||
{
 | 
			
		||||
    return &p->deleter();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) BOOST_SP_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lwm_nop.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef lightweight_mutex scoped_lock;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lwm_pthreads.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_t m_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
 | 
			
		||||
 | 
			
		||||
#if defined(__hpux) && defined(_DECTHREADS_)
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
 | 
			
		||||
#else
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~lightweight_mutex()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock;
 | 
			
		||||
    friend class scoped_lock;
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        pthread_mutex_t & m_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock(scoped_lock const &);
 | 
			
		||||
        scoped_lock & operator=(scoped_lock const &);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        scoped_lock(lightweight_mutex & m): m_(m.m_)
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
@@ -1,138 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lwm_win32_cs.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 Peter Dimov
 | 
			
		||||
//  Copyright (c) Microsoft Corporation 2014
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/predef.h>
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
struct _RTL_CRITICAL_SECTION;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
struct critical_section
 | 
			
		||||
{
 | 
			
		||||
    struct critical_section_debug * DebugInfo;
 | 
			
		||||
    long LockCount;
 | 
			
		||||
    long RecursionCount;
 | 
			
		||||
    void * OwningThread;
 | 
			
		||||
    void * LockSemaphore;
 | 
			
		||||
#if defined(_WIN64)
 | 
			
		||||
    unsigned __int64 SpinCount;
 | 
			
		||||
#else
 | 
			
		||||
    unsigned long SpinCount;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if BOOST_PLAT_WINDOWS_RUNTIME
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long);
 | 
			
		||||
#else
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *);
 | 
			
		||||
#endif
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *);
 | 
			
		||||
 | 
			
		||||
typedef ::_RTL_CRITICAL_SECTION rtl_critical_section;
 | 
			
		||||
 | 
			
		||||
#else // #ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
typedef ::CRITICAL_SECTION critical_section;
 | 
			
		||||
 | 
			
		||||
#if BOOST_PLAT_WINDOWS_RUNTIME
 | 
			
		||||
using ::InitializeCriticalSectionEx;
 | 
			
		||||
#else
 | 
			
		||||
using ::InitializeCriticalSection;
 | 
			
		||||
#endif
 | 
			
		||||
using ::EnterCriticalSection;
 | 
			
		||||
using ::LeaveCriticalSection;
 | 
			
		||||
using ::DeleteCriticalSection;
 | 
			
		||||
 | 
			
		||||
typedef ::CRITICAL_SECTION rtl_critical_section;
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    critical_section cs_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex()
 | 
			
		||||
    {
 | 
			
		||||
#if BOOST_PLAT_WINDOWS_RUNTIME
 | 
			
		||||
        boost::detail::InitializeCriticalSectionEx(reinterpret_cast< rtl_critical_section* >(&cs_), 4000, 0);
 | 
			
		||||
#else
 | 
			
		||||
        boost::detail::InitializeCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_));
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~lightweight_mutex()
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::DeleteCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock;
 | 
			
		||||
    friend class scoped_lock;
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        lightweight_mutex & m_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock(scoped_lock const &);
 | 
			
		||||
        scoped_lock & operator=(scoped_lock const &);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock(lightweight_mutex & m): m_(m)
 | 
			
		||||
        {
 | 
			
		||||
            boost::detail::EnterCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            boost::detail::LeaveCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_));
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
@@ -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 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/quick_allocator.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2003 David Abrahams
 | 
			
		||||
//  Copyright (c) 2003 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
 | 
			
		||||
#include <boost/type_traits/type_with_alignment.hpp>
 | 
			
		||||
#include <boost/type_traits/alignment_of.hpp>
 | 
			
		||||
 | 
			
		||||
#include <new>              // ::operator new, ::operator delete
 | 
			
		||||
#include <cstddef>          // std::size_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_> union freeblock
 | 
			
		||||
{
 | 
			
		||||
    typedef typename boost::type_with_alignment<align_>::type aligner_type;
 | 
			
		||||
    aligner_type aligner;
 | 
			
		||||
    char bytes[size];
 | 
			
		||||
    freeblock * next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_> struct allocator_impl
 | 
			
		||||
{
 | 
			
		||||
    typedef freeblock<size, align_> block;
 | 
			
		||||
 | 
			
		||||
    // It may seem odd to use such small pages.
 | 
			
		||||
    //
 | 
			
		||||
    // However, on a typical Windows implementation that uses
 | 
			
		||||
    // the OS allocator, "normal size" pages interact with the
 | 
			
		||||
    // "ordinary" operator new, slowing it down dramatically.
 | 
			
		||||
    //
 | 
			
		||||
    // 512 byte pages are handled by the small object allocator,
 | 
			
		||||
    // and don't interfere with ::new.
 | 
			
		||||
    //
 | 
			
		||||
    // The other alternative is to use much bigger pages (1M.)
 | 
			
		||||
    //
 | 
			
		||||
    // It is surprisingly easy to hit pathological behavior by
 | 
			
		||||
    // varying the page size. g++ 2.96 on Red Hat Linux 7.2,
 | 
			
		||||
    // for example, passionately dislikes 496. 512 seems OK.
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_QA_PAGE_SIZE)
 | 
			
		||||
 | 
			
		||||
    enum { items_per_page = BOOST_QA_PAGE_SIZE / size };
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    enum { items_per_page = 512 / size }; // 1048560 / size
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
 | 
			
		||||
    static lightweight_mutex & mutex()
 | 
			
		||||
    {
 | 
			
		||||
        static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
 | 
			
		||||
        static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
 | 
			
		||||
        return *pm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static lightweight_mutex * mutex_init;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    static block * free;
 | 
			
		||||
    static block * page;
 | 
			
		||||
    static unsigned last;
 | 
			
		||||
 | 
			
		||||
    static inline void * alloc()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
        lightweight_mutex::scoped_lock lock( mutex() );
 | 
			
		||||
#endif
 | 
			
		||||
        if(block * x = free)
 | 
			
		||||
        {
 | 
			
		||||
            free = x->next;
 | 
			
		||||
            return x;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if(last == items_per_page)
 | 
			
		||||
            {
 | 
			
		||||
                // "Listen to me carefully: there is no memory leak"
 | 
			
		||||
                // -- Scott Meyers, Eff C++ 2nd Ed Item 10
 | 
			
		||||
                page = ::new block[items_per_page];
 | 
			
		||||
                last = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return &page[last++];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static inline void * alloc(std::size_t n)
 | 
			
		||||
    {
 | 
			
		||||
        if(n != size) // class-specific new called for a derived object
 | 
			
		||||
        {
 | 
			
		||||
            return ::operator new(n);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
            lightweight_mutex::scoped_lock lock( mutex() );
 | 
			
		||||
#endif
 | 
			
		||||
            if(block * x = free)
 | 
			
		||||
            {
 | 
			
		||||
                free = x->next;
 | 
			
		||||
                return x;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if(last == items_per_page)
 | 
			
		||||
                {
 | 
			
		||||
                    page = ::new block[items_per_page];
 | 
			
		||||
                    last = 0;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return &page[last++];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static inline void dealloc(void * pv)
 | 
			
		||||
    {
 | 
			
		||||
        if(pv != 0) // 18.4.1.1/13
 | 
			
		||||
        {
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
            lightweight_mutex::scoped_lock lock( mutex() );
 | 
			
		||||
#endif
 | 
			
		||||
            block * pb = static_cast<block *>(pv);
 | 
			
		||||
            pb->next = free;
 | 
			
		||||
            free = pb;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static inline void dealloc(void * pv, std::size_t n)
 | 
			
		||||
    {
 | 
			
		||||
        if(n != size) // class-specific delete called for a derived object
 | 
			
		||||
        {
 | 
			
		||||
            ::operator delete(pv);
 | 
			
		||||
        }
 | 
			
		||||
        else if(pv != 0) // 18.4.1.1/13
 | 
			
		||||
        {
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
            lightweight_mutex::scoped_lock lock( mutex() );
 | 
			
		||||
#endif
 | 
			
		||||
            block * pb = static_cast<block *>(pv);
 | 
			
		||||
            pb->next = free;
 | 
			
		||||
            free = pb;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_>
 | 
			
		||||
  lightweight_mutex * allocator_impl<size, align_>::mutex_init = &allocator_impl<size, align_>::mutex();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_>
 | 
			
		||||
  freeblock<size, align_> * allocator_impl<size, align_>::free = 0;
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_>
 | 
			
		||||
  freeblock<size, align_> * allocator_impl<size, align_>::page = 0;
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_>
 | 
			
		||||
  unsigned allocator_impl<size, align_>::last = allocator_impl<size, align_>::items_per_page;
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of<T>::value >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
@@ -1,668 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/shared_count.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn -8027     // Functions containing try are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/throw_exception.hpp>
 | 
			
		||||
#include <boost/smart_ptr/bad_weak_ptr.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_noexcept.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
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_NO_EXCEPTIONS
 | 
			
		||||
# include <new>              // std::bad_alloc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/core/addressof.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace movelib
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template< class T, class D > class unique_ptr;
 | 
			
		||||
 | 
			
		||||
} // namespace movelib
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
int const shared_count_id = 0x2C35F101;
 | 
			
		||||
int const   weak_count_id = 0x298C38A4;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct sp_nothrow_tag {};
 | 
			
		||||
 | 
			
		||||
template< class D > struct sp_inplace_tag
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class T > class sp_reference_wrapper
 | 
			
		||||
{ 
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class Y > void operator()( Y * p ) const
 | 
			
		||||
    {
 | 
			
		||||
        (*t_)( p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * t_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class D > struct sp_convert_reference
 | 
			
		||||
{
 | 
			
		||||
    typedef D type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class D > struct sp_convert_reference< D& >
 | 
			
		||||
{
 | 
			
		||||
    typedef sp_reference_wrapper< D > type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class weak_count;
 | 
			
		||||
 | 
			
		||||
class shared_count
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base * pi_;
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
    int id_;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    friend class weak_count;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    BOOST_CONSTEXPR shared_count() BOOST_SP_NOEXCEPT: pi_(0)
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> explicit shared_count( Y * p ): pi_( 0 )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            pi_ = new sp_counted_impl_p<Y>( p );
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_delete( p );
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = new sp_counted_impl_p<Y>( p );
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_delete( p );
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
 | 
			
		||||
    template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
 | 
			
		||||
#else
 | 
			
		||||
    template<class P, class D> shared_count( P p, D d ): pi_(0)
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
 | 
			
		||||
        typedef Y* P;
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            pi_ = new sp_counted_impl_pd<P, D>(p, d);
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
            d(p); // delete p
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = new sp_counted_impl_pd<P, D>(p, d);
 | 
			
		||||
 | 
			
		||||
        if(pi_ == 0)
 | 
			
		||||
        {
 | 
			
		||||
            d(p); // delete p
 | 
			
		||||
            boost::throw_exception(std::bad_alloc());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
 | 
			
		||||
    template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            pi_ = new sp_counted_impl_pd< P, D >( p );
 | 
			
		||||
        }
 | 
			
		||||
        catch( ... )
 | 
			
		||||
        {
 | 
			
		||||
            D::operator_fn( p ); // delete p
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = new sp_counted_impl_pd< P, D >( p );
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            D::operator_fn( p ); // delete p
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
 | 
			
		||||
    template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        typedef sp_counted_impl_pda<P, D, A> impl_type;
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
        typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        typedef typename A::template rebind< impl_type >::other A2;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        A2 a2( a );
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            pi_ = a2.allocate( 1 );
 | 
			
		||||
            ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
            d( p );
 | 
			
		||||
 | 
			
		||||
            if( pi_ != 0 )
 | 
			
		||||
            {
 | 
			
		||||
                a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = a2.allocate( 1 );
 | 
			
		||||
 | 
			
		||||
        if( pi_ != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            d( p );
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
 | 
			
		||||
    template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        typedef sp_counted_impl_pda< P, D, A > impl_type;
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
        typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        typedef typename A::template rebind< impl_type >::other A2;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        A2 a2( a );
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            pi_ = a2.allocate( 1 );
 | 
			
		||||
            ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
            D::operator_fn( p );
 | 
			
		||||
 | 
			
		||||
            if( pi_ != 0 )
 | 
			
		||||
            {
 | 
			
		||||
                a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = a2.allocate( 1 );
 | 
			
		||||
 | 
			
		||||
        if( pi_ != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            D::operator_fn( p );
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    // auto_ptr<Y> is special cased to provide the strong guarantee
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
#ifdef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            boost::throw_exception(std::bad_alloc());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        r.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif 
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D>
 | 
			
		||||
    explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        typedef typename sp_convert_reference<D>::type D2;
 | 
			
		||||
 | 
			
		||||
        D2 d2( r.get_deleter() );
 | 
			
		||||
        pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        r.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D>
 | 
			
		||||
    explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        typedef typename sp_convert_reference<D>::type D2;
 | 
			
		||||
 | 
			
		||||
        D2 d2( r.get_deleter() );
 | 
			
		||||
        pi_ = new sp_counted_impl_pd< typename boost::movelib::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        r.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~shared_count() /*BOOST_SP_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
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
    {
 | 
			
		||||
        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 & operator= (shared_count const & r) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
 | 
			
		||||
        if( tmp != pi_ )
 | 
			
		||||
        {
 | 
			
		||||
            if( tmp != 0 ) tmp->add_ref_copy();
 | 
			
		||||
            if( pi_ != 0 ) pi_->release();
 | 
			
		||||
            pi_ = tmp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(shared_count & r) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
        r.pi_ = pi_;
 | 
			
		||||
        pi_ = tmp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pi_ != 0? pi_->use_count(): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool unique() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return use_count() == 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool empty() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pi_ == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    friend inline bool operator==(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return a.pi_ == b.pi_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    friend inline bool operator<(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * get_deleter( sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pi_? pi_->get_deleter( ti ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * get_local_deleter( sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pi_? pi_->get_local_deleter( ti ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * get_untyped_deleter() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pi_? pi_->get_untyped_deleter(): 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class weak_count
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base * pi_;
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
    int id_;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    friend class shared_count;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    BOOST_CONSTEXPR weak_count() BOOST_SP_NOEXCEPT: pi_(0)
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(weak_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    weak_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(weak_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        if(pi_ != 0) pi_->weak_add_ref();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    weak_count(weak_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(weak_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        if(pi_ != 0) pi_->weak_add_ref();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// Move support
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
    weak_count(weak_count && r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(weak_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        r.pi_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    ~weak_count() /*BOOST_SP_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
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
 | 
			
		||||
        if( tmp != pi_ )
 | 
			
		||||
        {
 | 
			
		||||
            if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
            if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
            pi_ = tmp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    weak_count & operator= (weak_count const & r) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
 | 
			
		||||
        if( tmp != pi_ )
 | 
			
		||||
        {
 | 
			
		||||
            if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
            if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
            pi_ = tmp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(weak_count & r) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
        r.pi_ = pi_;
 | 
			
		||||
        pi_ = tmp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pi_ != 0? pi_->use_count(): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool empty() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pi_ == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    friend inline bool operator==(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return a.pi_ == b.pi_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    friend inline bool operator<(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return std::less<sp_counted_base *>()(a.pi_, b.pi_);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
    if( pi_ == 0 || !pi_->add_ref_lock() )
 | 
			
		||||
    {
 | 
			
		||||
        boost::throw_exception( boost::bad_weak_ptr() );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_SP_NOEXCEPT: pi_( r.pi_ )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
    if( pi_ != 0 && !pi_->add_ref_lock() )
 | 
			
		||||
    {
 | 
			
		||||
        pi_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn .8027     // Functions containing try are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
@@ -1,92 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_convertible.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
 | 
			
		||||
# define BOOST_SP_NO_SP_CONVERTIBLE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
 | 
			
		||||
# define BOOST_SP_NO_SP_CONVERTIBLE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
 | 
			
		||||
# define BOOST_SP_NO_SP_CONVERTIBLE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > struct sp_convertible
 | 
			
		||||
{
 | 
			
		||||
    typedef char (&yes) [1];
 | 
			
		||||
    typedef char (&no)  [2];
 | 
			
		||||
 | 
			
		||||
    static yes f( T* );
 | 
			
		||||
    static no  f( ... );
 | 
			
		||||
 | 
			
		||||
    enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > struct sp_convertible< Y, T[] >
 | 
			
		||||
{
 | 
			
		||||
    enum _vt { value = false };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > struct sp_convertible< Y[], T[] >
 | 
			
		||||
{
 | 
			
		||||
    enum _vt { value = sp_convertible< Y[1], T[1] >::value };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
 | 
			
		||||
{
 | 
			
		||||
    enum _vt { value = sp_convertible< Y[1], T[1] >::value };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sp_empty
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< bool > struct sp_enable_if_convertible_impl;
 | 
			
		||||
 | 
			
		||||
template<> struct sp_enable_if_convertible_impl<true>
 | 
			
		||||
{
 | 
			
		||||
    typedef sp_empty type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct sp_enable_if_convertible_impl<false>
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2005-2013 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#if !defined( __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>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_STD_ATOMIC )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_SPINLOCK )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_PTHREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_clang.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined( 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( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__HP_aCC) && defined(__ia64)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __IBMCPP__ ) && defined( __powerpc )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !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>
 | 
			
		||||
 | 
			
		||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( _AIX )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_HAS_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef BOOST_SP_HAS_CLANG_C11_ATOMICS
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
@@ -1,153 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007 Baruch Zilber
 | 
			
		||||
//  Copyright 2007 Boris Gubenko
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <machine/sys/inline.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
 | 
			
		||||
    if (1 == r)
 | 
			
		||||
    {
 | 
			
		||||
        _Asm_mf();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return r - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int v = *pw;
 | 
			
		||||
    
 | 
			
		||||
    for (;;)
 | 
			
		||||
    {
 | 
			
		||||
        if (0 == v)
 | 
			
		||||
        {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        _Asm_mov_to_ar(_AREG_CCV,
 | 
			
		||||
                       v,
 | 
			
		||||
                       (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
 | 
			
		||||
        int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
 | 
			
		||||
        if (r == v)
 | 
			
		||||
        {
 | 
			
		||||
            return r + 1;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        v = r;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class 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_decrement( &use_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
 | 
			
		||||
@@ -1,145 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_aix.hpp
 | 
			
		||||
//   based on: detail/sp_counted_base_w32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//  Copyright 2006 Michael van der Westhuizen
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <builtins.h>
 | 
			
		||||
#include <sys/atomic_op.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int32_t* pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    fetch_and_add( pw, 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_decrement( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int32_t originalValue;
 | 
			
		||||
 | 
			
		||||
    __lwsync();
 | 
			
		||||
    originalValue = fetch_and_add( pw, -1 );
 | 
			
		||||
    __isync();
 | 
			
		||||
 | 
			
		||||
    return (originalValue - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_conditional_increment( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int32_t tmp = fetch_and_add( pw, 0 );
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        if( tmp == 0 ) return 0;
 | 
			
		||||
        if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    int32_t use_count_;        // #shared
 | 
			
		||||
    int32_t weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~sp_counted_base() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dispose() is called when use_count_ drops to zero, to release
 | 
			
		||||
    // the resources managed by *this.
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() = 0; // nothrow
 | 
			
		||||
 | 
			
		||||
    // destroy() is called when weak_count_ drops to zero.
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_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_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
@@ -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/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
 | 
			
		||||
@@ -1,173 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( register long * pw )
 | 
			
		||||
{
 | 
			
		||||
    register int a;
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
loop:
 | 
			
		||||
 | 
			
		||||
    lwarx   a, 0, pw
 | 
			
		||||
    addi    a, a, 1
 | 
			
		||||
    stwcx.  a, 0, pw
 | 
			
		||||
    bne-    loop
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline long atomic_decrement( register long * pw )
 | 
			
		||||
{
 | 
			
		||||
    register int a;
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
    sync
 | 
			
		||||
 | 
			
		||||
loop:
 | 
			
		||||
 | 
			
		||||
    lwarx   a, 0, pw
 | 
			
		||||
    addi    a, a, -1
 | 
			
		||||
    stwcx.  a, 0, pw
 | 
			
		||||
    bne-    loop
 | 
			
		||||
 | 
			
		||||
    isync
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline long atomic_conditional_increment( register long * pw )
 | 
			
		||||
{
 | 
			
		||||
    register int a;
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
loop:
 | 
			
		||||
 | 
			
		||||
    lwarx   a, 0, pw
 | 
			
		||||
    cmpwi   a, 0
 | 
			
		||||
    beq     store
 | 
			
		||||
 | 
			
		||||
    addi    a, a, 1
 | 
			
		||||
 | 
			
		||||
store:
 | 
			
		||||
 | 
			
		||||
    stwcx.  a, 0, pw
 | 
			
		||||
    bne-    loop
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    long use_count_;        // #shared
 | 
			
		||||
    long weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
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_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<long const volatile &>( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
@@ -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/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
 | 
			
		||||
@@ -1,160 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2006 Peter Dimov
 | 
			
		||||
//  Copyright 2005 Ben Hutchings
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    int tmp;
 | 
			
		||||
 | 
			
		||||
    // No barrier is required here but fetchadd always has an acquire or
 | 
			
		||||
    // release barrier associated with it.  We choose release as it should be
 | 
			
		||||
    // cheaper.
 | 
			
		||||
    __asm__ ("fetchadd4.rel %0=%1,1" :
 | 
			
		||||
         "=r"(tmp), "=m"(*pw) :
 | 
			
		||||
         "m"( *pw ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
    __asm__ ("     fetchadd4.rel %0=%1,-1 ;; \n"
 | 
			
		||||
             "     cmp.eq        p7,p0=1,%0 ;; \n"
 | 
			
		||||
             "(p7) ld4.acq       %0=%1    " :
 | 
			
		||||
             "=&r"(rv), "=m"(*pw) :
 | 
			
		||||
             "m"( *pw ) :
 | 
			
		||||
             "p7");
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int rv, tmp, tmp2;
 | 
			
		||||
 | 
			
		||||
    __asm__ ("0:   ld4          %0=%3           ;; \n"
 | 
			
		||||
         "     cmp.eq       p7,p0=0,%0        ;; \n"
 | 
			
		||||
         "(p7) br.cond.spnt 1f                \n"
 | 
			
		||||
         "     mov          ar.ccv=%0         \n"
 | 
			
		||||
         "     add          %1=1,%0           ;; \n"
 | 
			
		||||
         "     cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
 | 
			
		||||
         "     cmp.ne       p7,p0=%0,%2       ;; \n"
 | 
			
		||||
         "(p7) br.cond.spnt 0b                \n"
 | 
			
		||||
         "     mov          %0=%1             ;; \n"
 | 
			
		||||
         "1:" : 
 | 
			
		||||
         "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
 | 
			
		||||
         "m"( *pw ) :
 | 
			
		||||
         "ar.ccv", "p7");
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class 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_decrement( &use_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
@@ -1,190 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2009, Spirent Communications, Inc.
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    int tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
#if !defined(__mips_isa_rev) || (__mips_isa_rev < 6)
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
#endif
 | 
			
		||||
        "ll %0, %1\n\t"
 | 
			
		||||
        "addiu %0, 1\n\t"
 | 
			
		||||
        "sc %0, %1\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %0, 0b":
 | 
			
		||||
        "=&r"( tmp ), "=m"( *pw ):
 | 
			
		||||
        "m"( *pw )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int rv, tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
#if !defined(__mips_isa_rev) || (__mips_isa_rev < 6)
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
#endif
 | 
			
		||||
        "ll %1, %2\n\t"
 | 
			
		||||
        "addiu %0, %1, -1\n\t"
 | 
			
		||||
        "sc %0, %2\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %0, 0b\n\t"
 | 
			
		||||
        "addiu %0, %1, -1":
 | 
			
		||||
        "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
 | 
			
		||||
        "m"( *pw ):
 | 
			
		||||
        "memory"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int rv, tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
#if !defined(__mips_isa_rev) || (__mips_isa_rev < 6)
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
#endif
 | 
			
		||||
        "ll %0, %2\n\t"
 | 
			
		||||
        "beqz %0, 1f\n\t"
 | 
			
		||||
        "addiu %1, %0, 1\n\t"
 | 
			
		||||
        "sc %1, %2\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %1, 0b\n\t"
 | 
			
		||||
        "addiu %0, %0, 1\n\t"
 | 
			
		||||
        "1:":
 | 
			
		||||
        "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
 | 
			
		||||
        "m"( *pw ):
 | 
			
		||||
        "memory"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class 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_decrement( &use_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<int const volatile &>( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
 | 
			
		||||
@@ -1,184 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    int tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        "lwarx %1, 0, %2\n\t"
 | 
			
		||||
        "addi %1, %1, 1\n\t"
 | 
			
		||||
        "stwcx. %1, 0, %2\n\t"
 | 
			
		||||
        "bne- 0b":
 | 
			
		||||
 | 
			
		||||
        "=m"( *pw ), "=&b"( tmp ):
 | 
			
		||||
        "r"( pw ), "m"( *pw ):
 | 
			
		||||
        "cc"
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "sync\n\t"
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        "lwarx %1, 0, %2\n\t"
 | 
			
		||||
        "addi %1, %1, -1\n\t"
 | 
			
		||||
        "stwcx. %1, 0, %2\n\t"
 | 
			
		||||
        "bne- 0b\n\t"
 | 
			
		||||
        "isync":
 | 
			
		||||
 | 
			
		||||
        "=m"( *pw ), "=&b"( rv ):
 | 
			
		||||
        "r"( pw ), "m"( *pw ):
 | 
			
		||||
        "memory", "cc"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
    __asm__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        "lwarx %1, 0, %2\n\t"
 | 
			
		||||
        "cmpwi %1, 0\n\t"
 | 
			
		||||
        "beq 1f\n\t"
 | 
			
		||||
        "addi %1, %1, 1\n\t"
 | 
			
		||||
        "1:\n\t"
 | 
			
		||||
        "stwcx. %1, 0, %2\n\t"
 | 
			
		||||
        "bne- 0b":
 | 
			
		||||
 | 
			
		||||
        "=m"( *pw ), "=&b"( rv ):
 | 
			
		||||
        "r"( pw ), "m"( *pw ):
 | 
			
		||||
        "cc"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class 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_decrement( &use_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<int const volatile &>( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
@@ -1,169 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2006 Piotr Wyderski
 | 
			
		||||
//  Copyright (c) 2006 Tomas Puverle
 | 
			
		||||
//  Copyright (c) 2006 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Michael van der Westhuizen
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <inttypes.h> // int32_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
 | 
			
		||||
{
 | 
			
		||||
    __asm__ __volatile__( "cas [%1], %2, %0"
 | 
			
		||||
                        : "+r" (swap_)
 | 
			
		||||
                        : "r" (dest_), "r" (compare_)
 | 
			
		||||
                        : "memory" );
 | 
			
		||||
 | 
			
		||||
    return swap_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // *pw += dv;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        int32_t r = *pw;
 | 
			
		||||
 | 
			
		||||
        if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    atomic_fetch_and_add( pw, 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_decrement( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    return atomic_fetch_and_add( pw, -1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_conditional_increment( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // if( r != 0 ) ++*pw;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        int32_t r = *pw;
 | 
			
		||||
 | 
			
		||||
        if( r == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    int32_t use_count_;        // #shared
 | 
			
		||||
    int32_t weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~sp_counted_base() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dispose() is called when use_count_ drops to zero, to release
 | 
			
		||||
    // the resources managed by *this.
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() = 0; // nothrow
 | 
			
		||||
 | 
			
		||||
    // destroy() is called when weak_count_ drops to zero.
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_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 const_cast< int32_t const volatile & >( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
 | 
			
		||||
@@ -1,176 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
    int r;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "lock\n\t"
 | 
			
		||||
        "xadd %1, %0":
 | 
			
		||||
        "=m"( *pw ), "=r"( r ): // outputs (%0, %1)
 | 
			
		||||
        "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
 | 
			
		||||
        "memory", "cc" // clobbers
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    //atomic_exchange_and_add( pw, 1 );
 | 
			
		||||
 | 
			
		||||
    __asm__
 | 
			
		||||
    (
 | 
			
		||||
        "lock\n\t"
 | 
			
		||||
        "incl %0":
 | 
			
		||||
        "=m"( *pw ): // output (%0)
 | 
			
		||||
        "m"( *pw ): // input (%1)
 | 
			
		||||
        "cc" // clobbers
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // int rv = *pw;
 | 
			
		||||
    // if( rv != 0 ) ++*pw;
 | 
			
		||||
    // return rv;
 | 
			
		||||
 | 
			
		||||
    int rv, tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__
 | 
			
		||||
    (
 | 
			
		||||
        "movl %0, %%eax\n\t"
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        "test %%eax, %%eax\n\t"
 | 
			
		||||
        "je 1f\n\t"
 | 
			
		||||
        "movl %%eax, %2\n\t"
 | 
			
		||||
        "incl %2\n\t"
 | 
			
		||||
        "lock\n\t"
 | 
			
		||||
        "cmpxchgl %2, %0\n\t"
 | 
			
		||||
        "jne 0b\n\t"
 | 
			
		||||
        "1:":
 | 
			
		||||
        "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
 | 
			
		||||
        "m"( *pw ): // input (%3)
 | 
			
		||||
        "cc" // clobbers
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class 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_GCC_X86_HPP_INCLUDED
 | 
			
		||||
@@ -1,112 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_nt.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/cstdint.hpp>
 | 
			
		||||
 | 
			
		||||
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 & );
 | 
			
		||||
 | 
			
		||||
    boost::int_least32_t use_count_;        // #shared
 | 
			
		||||
    boost::int_least32_t weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), 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
 | 
			
		||||
    {
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success
 | 
			
		||||
    {
 | 
			
		||||
        if( use_count_ == 0 ) return false;
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        if( --use_count_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        ++weak_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        if( --weak_count_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return use_count_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
@@ -1,140 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_pt.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/cstdint.hpp>
 | 
			
		||||
#include <pthread.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 & );
 | 
			
		||||
 | 
			
		||||
    boost::int_least32_t use_count_;        // #shared
 | 
			
		||||
    boost::int_least32_t weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
    mutable pthread_mutex_t m_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 | 
			
		||||
    {
 | 
			
		||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
 | 
			
		||||
 | 
			
		||||
#if defined(__hpux) && defined(_DECTHREADS_)
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
 | 
			
		||||
#else
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~sp_counted_base() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dispose() is called when use_count_ drops to zero, to release
 | 
			
		||||
    // the resources managed by *this.
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() = 0; // nothrow
 | 
			
		||||
 | 
			
		||||
    // destroy() is called when weak_count_ drops to zero.
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() // true on success
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        bool r = use_count_ == 0? false: ( ++use_count_, true );
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        boost::int_least32_t new_use_count = --use_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
 | 
			
		||||
        if( new_use_count == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        ++weak_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        boost::int_least32_t new_weak_count = --weak_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
 | 
			
		||||
        if( new_weak_count == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        boost::int_least32_t r = use_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
@@ -1,164 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2006 Piotr Wyderski
 | 
			
		||||
//  Copyright (c) 2006 Tomas Puverle
 | 
			
		||||
//  Copyright (c) 2006 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2011 Emil Dotchevski
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Michael van der Westhuizen
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <inttypes.h> // uint32_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
 | 
			
		||||
{
 | 
			
		||||
    return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // *pw += dv;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t r = *pw;
 | 
			
		||||
 | 
			
		||||
        if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( uint32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    (void) __builtin_cellAtomicIncr32( pw );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t atomic_decrement( uint32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    return __builtin_cellAtomicDecr32( pw );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t atomic_conditional_increment( uint32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // if( r != 0 ) ++*pw;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t r = *pw;
 | 
			
		||||
 | 
			
		||||
        if( r == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class 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_increment( &use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() // true on success
 | 
			
		||||
    {
 | 
			
		||||
        return atomic_conditional_increment( &use_count_ ) != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &use_count_ ) == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return const_cast< uint32_t const volatile & >( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
 | 
			
		||||
@@ -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/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
 | 
			
		||||
@@ -1,134 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline int atomic_exchange_and_add( int * pw, int dv )
 | 
			
		||||
{
 | 
			
		||||
    spinlock_pool<1>::scoped_lock lock( pw );
 | 
			
		||||
 | 
			
		||||
    int r = *pw;
 | 
			
		||||
    *pw += dv;
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    spinlock_pool<1>::scoped_lock lock( pw );
 | 
			
		||||
    ++*pw;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    spinlock_pool<1>::scoped_lock lock( pw );
 | 
			
		||||
 | 
			
		||||
    int rv = *pw;
 | 
			
		||||
    if( rv != 0 ) ++*pw;
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class 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
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_pool<1>::scoped_lock lock( &use_count_ );
 | 
			
		||||
        return use_count_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
 | 
			
		||||
@@ -1,140 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_counted_base_std_atomic.hpp - C++11 std::atomic
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2007, 2013 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( std::atomic_int_least32_t * pw ) BOOST_SP_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
 | 
			
		||||
{
 | 
			
		||||
    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
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // if( r != 0 ) ++*pw;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    std::int_least32_t r = pw->load( std::memory_order_relaxed );
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        if( r == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    std::atomic_int_least32_t use_count_;   // #shared
 | 
			
		||||
    std::atomic_int_least32_t weak_count_;  // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), 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;
 | 
			
		||||
 | 
			
		||||
    // destroy() is called when weak_count_ drops to zero.
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() BOOST_SP_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;
 | 
			
		||||
 | 
			
		||||
    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 use_count_.load( std::memory_order_acquire );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
@@ -1,158 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2007 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
 | 
			
		||||
# include <ia64intrin.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if INT_MAX >= 2147483647
 | 
			
		||||
 | 
			
		||||
typedef int sp_int32_t;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
typedef long sp_int32_t;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( sp_int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    __sync_fetch_and_add( pw, 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline sp_int32_t atomic_decrement( sp_int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    return __sync_fetch_and_add( pw, -1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // if( r != 0 ) ++*pw;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    sp_int32_t r = *pw;
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        if( r == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
 | 
			
		||||
 | 
			
		||||
        if( r2 == r )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            r = r2;
 | 
			
		||||
        }
 | 
			
		||||
    }    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BOOST_SYMBOL_VISIBLE sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    sp_int32_t use_count_;        // #shared
 | 
			
		||||
    sp_int32_t weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~sp_counted_base() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dispose() is called when use_count_ drops to zero, to release
 | 
			
		||||
    // the resources managed by *this.
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() = 0; // nothrow
 | 
			
		||||
 | 
			
		||||
    // destroy() is called when weak_count_ drops to zero.
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_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 const_cast< sp_int32_t const volatile & >( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
 | 
			
		||||
@@ -1,153 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
 | 
			
		||||
//   based on: detail/sp_counted_base_w32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//  Copyright 2006 Michael van der Westhuizen
 | 
			
		||||
//  Copyright 2012 IBM Corp.
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
extern "builtin" void __lwsync(void);
 | 
			
		||||
extern "builtin" void __isync(void);
 | 
			
		||||
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
 | 
			
		||||
extern "builtin" int __compare_and_swap(volatile int*, int*, int);
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int *pw )
 | 
			
		||||
{
 | 
			
		||||
   // ++*pw;
 | 
			
		||||
   __lwsync();
 | 
			
		||||
   __fetch_and_add(pw, 1);
 | 
			
		||||
   __isync();
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int *pw )
 | 
			
		||||
{
 | 
			
		||||
   // return --*pw;
 | 
			
		||||
   __lwsync();
 | 
			
		||||
   int originalValue = __fetch_and_add(pw, -1);
 | 
			
		||||
   __isync();
 | 
			
		||||
 | 
			
		||||
   return (originalValue - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int *pw )
 | 
			
		||||
{
 | 
			
		||||
   // if( *pw != 0 ) ++*pw;
 | 
			
		||||
   // return *pw;
 | 
			
		||||
 | 
			
		||||
   __lwsync();
 | 
			
		||||
   int v = *const_cast<volatile int*>(pw);
 | 
			
		||||
   for (;;)
 | 
			
		||||
   // loop until state is known
 | 
			
		||||
   {
 | 
			
		||||
      if (v == 0) return 0;
 | 
			
		||||
      if (__compare_and_swap(pw, &v, v + 1))
 | 
			
		||||
      {
 | 
			
		||||
         __isync(); return (v + 1);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class 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)
 | 
			
		||||
    char pad[64] __attribute__((__aligned__(64)));
 | 
			
		||||
            // pad to prevent false sharing
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~sp_counted_base() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dispose() is called when use_count_ drops to zero, to release
 | 
			
		||||
    // the resources managed by *this.
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() = 0; // nothrow
 | 
			
		||||
 | 
			
		||||
    // destroy() is called when weak_count_ drops to zero.
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_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_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return *const_cast<volatile int*>(&use_count_); 
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
 | 
			
		||||
@@ -1,133 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_w32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
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 & );
 | 
			
		||||
 | 
			
		||||
    long use_count_;        // #shared
 | 
			
		||||
    long weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~sp_counted_base() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dispose() is called when use_count_ drops to zero, to release
 | 
			
		||||
    // the resources managed by *this.
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() = 0; // nothrow
 | 
			
		||||
 | 
			
		||||
    // destroy() is called when weak_count_ drops to zero.
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() // true on success
 | 
			
		||||
    {
 | 
			
		||||
        for( ;; )
 | 
			
		||||
        {
 | 
			
		||||
            long tmp = static_cast< long const volatile& >( use_count_ );
 | 
			
		||||
            if( tmp == 0 ) return false;
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
 | 
			
		||||
 | 
			
		||||
            // work around a code generation bug
 | 
			
		||||
 | 
			
		||||
            long tmp2 = tmp + 1;
 | 
			
		||||
            if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
            if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( BOOST_SP_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<long const volatile &>( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
@@ -1,293 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_impl.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
 | 
			
		||||
#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 <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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// get_local_deleter
 | 
			
		||||
 | 
			
		||||
template<class D> class local_sp_deleter;
 | 
			
		||||
 | 
			
		||||
template<class D> D * get_local_deleter( D * /*p*/ ) BOOST_SP_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X * px_;
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_p( sp_counted_impl_p const & );
 | 
			
		||||
    sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
 | 
			
		||||
 | 
			
		||||
    typedef sp_counted_impl_p<X> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit sp_counted_impl_p( X * px ): px_( px )
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_constructor_hook( px, sizeof(X), this );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
#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
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_local_deleter( sp_typeinfo const & ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pd( sp_counted_impl_pd const & );
 | 
			
		||||
    sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
 | 
			
		||||
 | 
			
		||||
    typedef sp_counted_impl_pd<P, D> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // pre: d(p) must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pd( P p ): ptr( p ), del()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        del( ptr );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    P p_; // copy constructor must not throw
 | 
			
		||||
    D d_; // copy constructor must not throw
 | 
			
		||||
    A a_; // copy constructor must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pda( sp_counted_impl_pda const & );
 | 
			
		||||
    sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
 | 
			
		||||
 | 
			
		||||
    typedef sp_counted_impl_pda<P, D, A> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // pre: d( p ) must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        d_( p_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
#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();
 | 
			
		||||
 | 
			
		||||
        a2.deallocate( this, 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return &reinterpret_cast<char&>( d_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __CODEGUARD__
 | 
			
		||||
# pragma option pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
@@ -1,40 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/smart_ptr/detail/sp_disable_deprecated.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2015 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( __GNUC__ ) && ( defined( __GXX_EXPERIMENTAL_CXX0X__ ) || ( __cplusplus >= 201103L ) )
 | 
			
		||||
 | 
			
		||||
# if defined( BOOST_GCC )
 | 
			
		||||
 | 
			
		||||
#  if BOOST_GCC >= 40600
 | 
			
		||||
#   define BOOST_SP_DISABLE_DEPRECATED
 | 
			
		||||
#  endif
 | 
			
		||||
 | 
			
		||||
# elif defined( __clang__ ) && defined( __has_warning )
 | 
			
		||||
 | 
			
		||||
#  if __has_warning( "-Wdeprecated-declarations" )
 | 
			
		||||
#   define BOOST_SP_DISABLE_DEPRECATED
 | 
			
		||||
#  endif
 | 
			
		||||
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -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
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user