mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-10-15 00:45:29 +02:00
Compare commits
3 Commits
boost-1.64
...
boost-1.32
Author | SHA1 | Date | |
---|---|---|---|
|
337e414515 | ||
|
aa00436b68 | ||
|
8a47b48f0e |
274
.travis.yml
274
.travis.yml
@@ -1,274 +0,0 @@
|
||||
# Copyright 2016 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
|
||||
exclude:
|
||||
- env: BOGUS_JOB=true
|
||||
|
||||
include:
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++03
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.6
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.6
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: osx
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03
|
||||
|
||||
- os: osx
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11
|
||||
|
||||
- os: osx
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone -b $TRAVIS_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/core
|
||||
- git submodule init libs/detail
|
||||
- git submodule init libs/functional
|
||||
- git submodule init libs/integer
|
||||
- git submodule init libs/move
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/preprocessor
|
||||
- git submodule init libs/static_assert
|
||||
- git submodule init libs/throw_exception
|
||||
- git submodule init libs/type_traits
|
||||
- git submodule init tools/build
|
||||
- git submodule update
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/smart_ptr
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam
|
||||
- ./b2 libs/smart_ptr/test toolset=$TOOLSET
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
@@ -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)
|
41
appveyor.yml
41
appveyor.yml
@@ -1,41 +0,0 @@
|
||||
# Copyright 2016 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone -b %APPVEYOR_REPO_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/core
|
||||
- git submodule init libs/detail
|
||||
- git submodule init libs/functional
|
||||
- git submodule init libs/integer
|
||||
- git submodule init libs/move
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/preprocessor
|
||||
- git submodule init libs/static_assert
|
||||
- git submodule init libs/throw_exception
|
||||
- git submodule init libs/type_traits
|
||||
- git submodule init tools/build
|
||||
- git submodule update
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\smart_ptr
|
||||
- bootstrap
|
||||
- b2 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- b2 libs/smart_ptr/test toolset=msvc-9.0,msvc-10.0,msvc-11.0,msvc-14.0
|
@@ -1,88 +1,105 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Smart Pointer Changes</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<title>Smart Pointer Changes</title>
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||
width="277" align="middle" border="0">Smart Pointer Changes</h1>
|
||||
<p>The February 2002 change to the Boost smart pointers introduced a number of
|
||||
changes. Since the previous version of the smart pointers was in use for a long
|
||||
time, it's useful to have a detailed list of what changed from a library user's
|
||||
point of view.</p>
|
||||
<p>Note that for compilers that don't support member templates well enough, a
|
||||
separate implementation is used that lacks many of the new features and is more
|
||||
like the old version.</p>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86">Smart
|
||||
Pointer Changes</h1>
|
||||
|
||||
<p>The February 2002 change to the Boost smart pointers introduced a number
|
||||
of changes. Since the previous version of the smart pointers was in use for
|
||||
a long time, it's useful to have a detailed list of what changed from a library
|
||||
user's point of view.</p>
|
||||
|
||||
<p>Note that for compilers that don't support member templates well enough,
|
||||
a separate implementation is used that lacks many of the new features and is
|
||||
more like the old version.</p>
|
||||
|
||||
<h2>Features Requiring Code Changes to Take Advantage</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The smart pointer class templates now each have their own header file. For
|
||||
compatibility, the <a href="../../boost/smart_ptr.hpp"><boost/smart_ptr.hpp></a>
|
||||
header now includes the headers for the four classic smart pointer class
|
||||
templates.
|
||||
<li>
|
||||
The <b>weak_ptr</b>
|
||||
template was added.
|
||||
<li>
|
||||
The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that
|
||||
the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
|
||||
destructor. This makes it easier to have shared_ptr members in classes without
|
||||
explicit destructors.
|
||||
<li>
|
||||
A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
|
||||
<li>
|
||||
<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
|
||||
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
|
||||
and <b>dynamic_cast</b>
|
||||
do for pointers.
|
||||
<li>
|
||||
The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
|
||||
|
||||
<li>The smart pointer class templates now each have their own header file.
|
||||
For compatibility, the
|
||||
<a href="../../boost/smart_ptr.hpp"><boost/smart_ptr.hpp></a>
|
||||
header now includes the headers for the four classic smart pointer class templates.</li>
|
||||
|
||||
<li>The <b>weak_ptr</b> template was added.</li>
|
||||
|
||||
<li>The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that the pointed-to object's
|
||||
destructor must be visible when instantiating the <b>shared_ptr</b> destructor.
|
||||
This makes it easier to have shared_ptr members in classes without explicit destructors.</li>
|
||||
|
||||
<li>A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.</li>
|
||||
|
||||
<li><b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
|
||||
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b> and
|
||||
<b>dynamic_cast</b> do for pointers.</li>
|
||||
|
||||
<li>The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
|
||||
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
|
||||
Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
|
||||
results in undefined behavior (an assertion, or eventually a double-delete if
|
||||
assertions are off).
|
||||
<li>
|
||||
The <b>BOOST_SMART_PTR_CONVERSION</b>
|
||||
feature has been removed.
|
||||
<li>
|
||||
<b>shared_ptr<void></b> is now allowed.</li>
|
||||
Calling <b>reset</b> with a pointer to the object that's already owned by the
|
||||
<b>shared_ptr</b> results in undefined behavior
|
||||
(an assertion, or eventually a double-delete if assertions are off).</li>
|
||||
|
||||
<li>The <b>BOOST_SMART_PTR_CONVERSION</b> feature has been removed.</li>
|
||||
|
||||
<li><b>shared_ptr<void></b> is now allowed.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Features That Improve Robustness</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The manipulation of use counts is now <a name="threadsafe">thread safe</a> on
|
||||
Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp">
|
||||
<boost/detail/atomic_count.hpp></a>
|
||||
file for details
|
||||
<li>
|
||||
The new shared_ptr will always delete the object using the pointer it was
|
||||
originally constructed with. This prevents subtle problems that could happen if
|
||||
the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did
|
||||
not have a virtual destructor.</li>
|
||||
|
||||
<li>The manipulation of use counts is now <a name="threadsafe">thread safe</a> on Windows, Linux, and platforms
|
||||
that support pthreads. See the
|
||||
<a href="../../boost/detail/atomic_count.hpp"><boost/detail/atomic_count.hpp></a>
|
||||
file for details</li>
|
||||
|
||||
<li>The new shared_ptr will always delete the object using the pointer it was originally constructed with.
|
||||
This prevents subtle problems that could happen if the last <b>shared_ptr</b> was a pointer to a sub-object
|
||||
of a class that did not have a virtual destructor.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Implementation Details</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Some bugs in the assignment operator implementations and in <b>reset</b>
|
||||
have been fixed by using the "copy and swap" idiom.
|
||||
<li>
|
||||
Assertions have been added to check preconditions of various functions;
|
||||
however, since these use the new <a href="../../boost/assert.hpp"><boost/assert.hpp></a>
|
||||
header, the assertions are disabled by default.
|
||||
<li>
|
||||
The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
|
||||
overloads which accomplish the same thing without relying on undefined
|
||||
behavior.
|
||||
<li>
|
||||
The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>,
|
||||
which has many of the same advantages for generic programming but does not
|
||||
violate the C++ standard.</li>
|
||||
|
||||
<li>Some bugs in the assignment operator implementations and in <b>reset</b>
|
||||
have been fixed by using the "copy and swap" idiom.</li>
|
||||
|
||||
<li>Assertions have been added to check preconditions of various functions;
|
||||
however, since these use the new
|
||||
<a href="../../boost/assert.hpp"><boost/assert.hpp></a>
|
||||
header, the assertions are disabled by default.</li>
|
||||
|
||||
<li>The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
|
||||
overloads which accomplish the same thing without relying on undefined behavior.</li>
|
||||
|
||||
<li>The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>, which
|
||||
has many of the same advantages for generic programming but does not violate the C++ standard.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p>$Date$</p>
|
||||
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
|
||||
<p>Revised 1 February 2002</p>
|
||||
|
||||
<p>Copyright 2002 Darin Adler.
|
||||
Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
@@ -1,51 +1,54 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>enable_shared_from_this</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>Boost: enable_shared_from_this.hpp documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||
width="277" align="middle" border="0" />enable_shared_from_this</h1>
|
||||
<h2><a name="Purpose">Purpose</a></h2>
|
||||
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="277">
|
||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
|
||||
</td>
|
||||
<td align="middle">
|
||||
<h1>enable_shared_from_this.hpp</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" height="64"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3><a name="Purpose">Purpose</a></h3>
|
||||
<p>
|
||||
The header <code><boost/enable_shared_from_this.hpp></code> defines
|
||||
the class template <code>enable_shared_from_this</code>. It is used as a
|
||||
base class that allows a <a href="shared_ptr.htm">shared_ptr</a> or
|
||||
a <a href="weak_ptr.htm">weak_ptr</a> to the current object to be obtained
|
||||
from within a member function.
|
||||
The header <STRONG><boost/enable_shared_from_this.hpp></STRONG> defines
|
||||
the class template <STRONG>enable_shared_from_this</STRONG>. It is used as a
|
||||
base class that allows a <A href="shared_ptr.htm">shared_ptr</A> to the current
|
||||
object to be obtained from within a member function.
|
||||
</p>
|
||||
<p><code>enable_shared_from_this<T></code> defines two member functions
|
||||
called <code>shared_from_this</code> that return a <code>shared_ptr<T></code>
|
||||
and <code>shared_ptr<T const></code>, depending on constness, to <code>this</code>.
|
||||
It also defines two member functions called <code>weak_from_this</code> that return
|
||||
a corresponding <code>weak_ptr</code>.
|
||||
</p>
|
||||
<h2><a name="Example">Example</a></h2>
|
||||
<P><STRONG>enable_shared_from_this<T></STRONG> defines two member functions
|
||||
called <STRONG>shared_from_this</STRONG> that return a <STRONG>shared_ptr<T></STRONG>
|
||||
and <STRONG>shared_ptr<T const></STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
|
||||
<h3><a name="Example">Example</a></h3>
|
||||
<pre>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <cassert>
|
||||
|
||||
class Y: public boost::enable_shared_from_this<Y>
|
||||
class Y: public enable_shared_from_this<Y>
|
||||
{
|
||||
public:
|
||||
|
||||
boost::shared_ptr<Y> f()
|
||||
shared_ptr<Y> f()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<Y> p(new Y);
|
||||
boost::shared_ptr<Y> q = p->f();
|
||||
shared_ptr<Y> p(new Y);
|
||||
shared_ptr<Y> q = p->f();
|
||||
assert(p == q);
|
||||
assert(!(p < q || q < p)); // p and q must share ownership
|
||||
}
|
||||
</pre>
|
||||
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||
<h3><a name="Synopsis">Synopsis</a></h3>
|
||||
<pre>
|
||||
namespace boost
|
||||
{
|
||||
@@ -56,55 +59,35 @@ public:
|
||||
|
||||
shared_ptr<T> shared_from_this();
|
||||
shared_ptr<T const> shared_from_this() const;
|
||||
|
||||
weak_ptr<T> weak_from_this() noexcept;
|
||||
weak_ptr<T const> weak_from_this() const noexcept;
|
||||
}
|
||||
|
||||
}
|
||||
</pre>
|
||||
<h4><code>template<class T> shared_ptr<T>
|
||||
enable_shared_from_this<T>::shared_from_this();</code></h4>
|
||||
<h4><code>template<class T> shared_ptr<T const>
|
||||
enable_shared_from_this<T>::shared_from_this() const;</code></h4>
|
||||
<h4>template<class T> shared_ptr<T>
|
||||
enable_shared_from_this<T>::shared_from_this();</h4>
|
||||
<h4>template<class T> shared_ptr<T const>
|
||||
enable_shared_from_this<T>::shared_from_this() const;</h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Requires:</b> <code>enable_shared_from_this<T></code> must be an
|
||||
accessible base class of <code>T</code>. <code>*this</code> must be a subobject
|
||||
of an instance <code>t</code> of type <code>T</code>.
|
||||
<b>Requires:</b> <STRONG>enable_shared_from_this<T></STRONG> must be an
|
||||
accessible base class of <b>T</b>. <STRONG>*this</STRONG> must be a subobject
|
||||
of an instance <STRONG>t</STRONG> of type <STRONG>T</STRONG> . There must exist
|
||||
at least one <STRONG>shared_ptr</STRONG> instance <STRONG>p</STRONG> that <EM>owns</EM>
|
||||
<STRONG>t</STRONG>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Returns:</b> If a <code>shared_ptr</code> instance <code>p</code> that <em>owns</em>
|
||||
<code>t</code> exists, a <code>shared_ptr<T></code> instance <code>r</code> that shares
|
||||
ownership with <code>p</code>.
|
||||
<b>Returns:</b> A <b>shared_ptr<T></b> instance <b>r</b> that shares
|
||||
ownership with <b>p</b>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Postconditions:</b> <code>r.get() == this</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Throws:</b> <code>bad_weak_ptr</code> when no <code>shared_ptr</code> <em>owns</em> <code>*this</code>.
|
||||
<b>Postconditions:</b> <tt>r.get() == this</tt>.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><code>template<class T> weak_ptr<T>
|
||||
enable_shared_from_this<T>::weak_from_this() noexcept;</code></h4>
|
||||
<h4><code>template<class T> weak_ptr<T const>
|
||||
enable_shared_from_this<T>::weak_from_this() const noexcept;</code></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Requires:</b> <code>enable_shared_from_this<T></code> must be an
|
||||
accessible base class of <code>T</code>. <code>*this</code> must be a subobject
|
||||
of an instance <code>t</code> of type <code>T</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Returns:</b> If a <code>shared_ptr</code> instance <code>p</code> that <em>owns</em>
|
||||
<code>t</code> exists or has existed in the past, a <code>weak_ptr<T></code> instance
|
||||
<code>r</code> that shares ownership with <code>p</code>. Otherwise, an empty <code>weak_ptr</code>.
|
||||
</p>
|
||||
</blockquote>
|
||||
<hr />
|
||||
<p>
|
||||
<small>Copyright © 2002, 2003, 2015 by Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
|
||||
copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
|
||||
<br>
|
||||
<small>Copyright <20> 2002, 2003 by Peter Dimov. Permission to copy, use, modify, sell
|
||||
and distribute this document is granted provided this copyright notice appears
|
||||
in all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -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();
|
||||
|
||||
pthread_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 )
|
||||
{
|
||||
pthread_join( a[j], 0 );
|
||||
}
|
||||
|
||||
t = clock() - t;
|
||||
|
||||
printf( "\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC );
|
||||
|
||||
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<pthread_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 )
|
||||
{
|
||||
pthread_join( a[ j ], 0 );
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
pthread_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 )
|
||||
{
|
||||
pthread_join( a[ j ], 0 );
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
pthread_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 )
|
||||
{
|
||||
pthread_join( a[j], 0 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
@@ -12,10 +12,102 @@
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
//
|
||||
// ++a;
|
||||
//
|
||||
// Effects: Atomically increments the value of a
|
||||
// Returns: nothing
|
||||
//
|
||||
// --a;
|
||||
//
|
||||
// Effects: Atomically decrements the value of a
|
||||
// Returns: (long) zero if the new value of a is zero,
|
||||
// unspecified non-zero value otherwise (usually the new value)
|
||||
//
|
||||
// Important note: when --a returns zero, it must act as a
|
||||
// read memory barrier (RMB); i.e. the calling thread must
|
||||
// have a synchronized view of the memory
|
||||
//
|
||||
// On Intel IA-32 (x86) memory is always synchronized, so this
|
||||
// is not a problem.
|
||||
//
|
||||
// On many architectures the atomic instructions already act as
|
||||
// a memory barrier.
|
||||
//
|
||||
// This property is necessary for proper reference counting, since
|
||||
// a thread can update the contents of a shared object, then
|
||||
// release its reference, and another thread may immediately
|
||||
// release the last reference causing object destruction.
|
||||
//
|
||||
// The destructor needs to have a synchronized view of the
|
||||
// object to perform proper cleanup.
|
||||
//
|
||||
// Original example by Alexander Terekhov:
|
||||
//
|
||||
// Given:
|
||||
//
|
||||
// - a mutable shared object OBJ;
|
||||
// - two threads THREAD1 and THREAD2 each holding
|
||||
// a private smart_ptr object pointing to that OBJ.
|
||||
//
|
||||
// t1: THREAD1 updates OBJ (thread-safe via some synchronization)
|
||||
// and a few cycles later (after "unlock") destroys smart_ptr;
|
||||
//
|
||||
// t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization
|
||||
// with respect to shared mutable object OBJ; OBJ destructors
|
||||
// are called driven by smart_ptr interface...
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
|
||||
// Note: atomic_count_linux.hpp has been disabled by default; see the
|
||||
// comments inside for more info.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifndef BOOST_HAS_THREADS
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef long atomic_count;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#elif defined(BOOST_USE_ASM_ATOMIC_H)
|
||||
# include <boost/detail/atomic_count_linux.hpp>
|
||||
#elif defined(BOOST_AC_USE_PTHREADS)
|
||||
# include <boost/detail/atomic_count_pthreads.hpp>
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
# include <boost/detail/atomic_count_win32.hpp>
|
||||
#elif defined(__GLIBCPP__)
|
||||
# include <boost/detail/atomic_count_gcc.hpp>
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# define BOOST_AC_USE_PTHREADS
|
||||
# include <boost/detail/atomic_count_pthreads.hpp>
|
||||
#else
|
||||
|
||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||
#error Unrecognized threading platform
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_gcc.hpp
|
||||
@@ -10,18 +10,13 @@
|
||||
//
|
||||
// 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
|
||||
{
|
||||
@@ -29,22 +24,15 @@ 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++()
|
||||
void operator++()
|
||||
{
|
||||
return __exchange_and_add( &value_, +1 ) + 1;
|
||||
__atomic_add(&value_, 1);
|
||||
}
|
||||
|
||||
long operator--()
|
||||
@@ -69,4 +57,4 @@ private:
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
69
include/boost/detail/atomic_count_linux.hpp
Normal file
69
include/boost/detail/atomic_count_linux.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_linux.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)
|
||||
//
|
||||
|
||||
//
|
||||
// This implementation uses <asm/atomic.h>. This is a kernel header;
|
||||
// using kernel headers in a user program may cause a number of problems,
|
||||
// and not all flavors of Linux provide the atomic instructions.
|
||||
//
|
||||
// This file is only provided because the performance of this implementation
|
||||
// is significantly higher than the pthreads version. Use at your own risk
|
||||
// (by defining BOOST_USE_ASM_ATOMIC_H.)
|
||||
//
|
||||
|
||||
#include <asm/atomic.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count(long v)
|
||||
{
|
||||
atomic_t init = ATOMIC_INIT(v);
|
||||
value_ = init;
|
||||
}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
atomic_inc(&value_);
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return !atomic_dec_and_test(&value_);
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return atomic_read(&value_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
atomic_t value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
|
@@ -1,5 +1,5 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_pthreads.hpp
|
||||
@@ -11,7 +11,6 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
//
|
||||
@@ -38,12 +37,12 @@ private:
|
||||
|
||||
scoped_lock(pthread_mutex_t & m): m_(m)
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
pthread_mutex_lock(&m_);
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
pthread_mutex_unlock(&m_);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -55,18 +54,18 @@ public:
|
||||
|
||||
explicit atomic_count(long v): value_(v)
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 );
|
||||
pthread_mutex_init(&mutex_, 0);
|
||||
}
|
||||
|
||||
~atomic_count()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 );
|
||||
pthread_mutex_destroy(&mutex_);
|
||||
}
|
||||
|
||||
long operator++()
|
||||
void operator++()
|
||||
{
|
||||
scoped_lock lock(mutex_);
|
||||
return ++value_;
|
||||
++value_;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
@@ -94,4 +93,4 @@ private:
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
97
include/boost/detail/atomic_count_win32.hpp
Normal file
97
include/boost/detail/atomic_count_win32.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
||||
#define BOOST_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, 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)
|
||||
//
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
|
||||
|
||||
extern "C" long_type __cdecl _InterlockedIncrement(long volatile *);
|
||||
extern "C" long_type __cdecl _InterlockedDecrement(long volatile *);
|
||||
|
||||
#pragma intrinsic(_InterlockedIncrement)
|
||||
#pragma intrinsic(_InterlockedDecrement)
|
||||
|
||||
inline long InterlockedIncrement(long volatile * lp)
|
||||
{
|
||||
return _InterlockedIncrement(lp);
|
||||
}
|
||||
|
||||
inline long InterlockedDecrement(long volatile* lp)
|
||||
{
|
||||
return _InterlockedDecrement(lp);
|
||||
}
|
||||
|
||||
#else // _WIN64
|
||||
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile *);
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile *);
|
||||
|
||||
#endif // _WIN64
|
||||
|
||||
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count(long v): value_(v)
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
// Some older <windows.h> versions do not accept volatile
|
||||
return InterlockedIncrement(const_cast<long*>(&value_));
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return InterlockedDecrement(const_cast<long*>(&value_));
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
volatile long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
@@ -12,11 +12,87 @@
|
||||
//
|
||||
// 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
|
||||
// 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 meets a subset of the Mutex concept
|
||||
// requirements: http://www.boost.org/libs/thread/doc/mutex_concept.html#Mutex
|
||||
//
|
||||
// * Used by the smart pointer library
|
||||
// * Performance oriented
|
||||
// * Header-only implementation
|
||||
// * Small memory footprint
|
||||
// * Not a general purpose mutex, use boost::mutex, CRITICAL_SECTION or
|
||||
// pthread_mutex instead.
|
||||
// * Never spin in a tight lock/do-something/unlock loop, since
|
||||
// lightweight_mutex does not guarantee fairness.
|
||||
// * Never keep a lightweight_mutex locked for long periods.
|
||||
//
|
||||
// The current implementation can use a pthread_mutex, a CRITICAL_SECTION,
|
||||
// or a platform-specific spinlock.
|
||||
//
|
||||
// You can force a particular implementation by defining BOOST_LWM_USE_PTHREADS,
|
||||
// BOOST_LWM_USE_CRITICAL_SECTION, or BOOST_LWM_USE_SPINLOCK.
|
||||
//
|
||||
// If neither macro has been defined, the default is to use a spinlock on Win32,
|
||||
// and a pthread_mutex otherwise.
|
||||
//
|
||||
// Note that a spinlock is not a general synchronization primitive. In particular,
|
||||
// it is not guaranteed to be a memory barrier, and it is possible to "livelock"
|
||||
// if a lower-priority thread has acquired the spinlock but a higher-priority
|
||||
// thread is spinning trying to acquire the same lock.
|
||||
//
|
||||
// For these reasons, spinlocks have been disabled by default except on Windows,
|
||||
// where a spinlock can be several orders of magnitude faster than a CRITICAL_SECTION.
|
||||
|
||||
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
|
||||
|
||||
// Note: lwm_linux.hpp has been disabled by default; see the comments
|
||||
// inside for more info.
|
||||
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Note to implementors: if you write a platform-specific spinlock
|
||||
// for a platform that supports pthreads, be sure to test its performance
|
||||
// against the pthreads-based version using shared_ptr_timing_test.cpp and
|
||||
// shared_ptr_mt_test.cpp. Custom versions are usually not worth the trouble
|
||||
// _unless_ the performance gains are substantial.
|
||||
//
|
||||
// Be sure to compare against a "real" pthreads library;
|
||||
// shared_ptr_timing_test.cpp will compile succesfully with a stub do-nothing
|
||||
// pthreads library, since it doesn't create any threads.
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(BOOST_LWM_USE_CRITICAL_SECTION) && !defined(BOOST_LWM_USE_PTHREADS)
|
||||
# define BOOST_LWM_WIN32
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_HAS_THREADS)
|
||||
# if defined(BOOST_LWM_WIN32)
|
||||
# include <boost/detail/lwm_win32_nt.hpp>
|
||||
# else
|
||||
# include <boost/detail/lwm_nop.hpp>
|
||||
# endif
|
||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(BOOST_USE_ASM_ATOMIC_H)
|
||||
# include <boost/detail/lwm_linux.hpp>
|
||||
#elif defined(BOOST_LWM_USE_CRITICAL_SECTION)
|
||||
# include <boost/detail/lwm_win32_cs.hpp>
|
||||
#elif defined(BOOST_LWM_USE_PTHREADS)
|
||||
# include <boost/detail/lwm_pthreads.hpp>
|
||||
#elif defined(BOOST_LWM_WIN32)
|
||||
# include <boost/detail/lwm_win32.hpp>
|
||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__sgi)
|
||||
# include <boost/detail/lwm_irix.hpp>
|
||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__GLIBCPP__)
|
||||
# include <boost/detail/lwm_gcc.hpp>
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# define BOOST_LWM_USE_PTHREADS
|
||||
# include <boost/detail/lwm_pthreads.hpp>
|
||||
#else
|
||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||
# error Unrecognized threading platform
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
|
@@ -1,135 +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 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <cerrno>
|
||||
|
||||
// pthread_create, pthread_join
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
typedef HANDLE pthread_t;
|
||||
|
||||
int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
|
||||
{
|
||||
HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
|
||||
|
||||
if( h != 0 )
|
||||
{
|
||||
*thread = h;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_join( pthread_t thread, void ** /*value_ptr*/ )
|
||||
{
|
||||
::WaitForSingleObject( thread, INFINITE );
|
||||
::CloseHandle( thread );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// template<class F> int lw_thread_create( pthread_t & pt, F f );
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lw_abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~lw_abstract_thread() {}
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
extern "C" void * lw_thread_routine( void * pv )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
|
||||
|
||||
pt->run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
unsigned __stdcall lw_thread_routine( void * pv )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
|
||||
|
||||
pt->run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class F> class lw_thread_impl: public lw_abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
explicit lw_thread_impl( F f ): f_( f )
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
f_();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
F f_;
|
||||
};
|
||||
|
||||
template<class F> int lw_thread_create( pthread_t & pt, F f )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
|
||||
|
||||
int r = pthread_create( &pt, 0, lw_thread_routine, p.get() );
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
p.release();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
77
include/boost/detail/lwm_gcc.hpp
Normal file
77
include/boost/detail/lwm_gcc.hpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/lwm_gcc.hpp
|
||||
//
|
||||
// lightweight_mutex for GNU libstdc++ v3
|
||||
//
|
||||
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2002 Lars Gullik Bj<42>nnes <larsbj@lyx.org>
|
||||
//
|
||||
// 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 <bits/atomicity.h>
|
||||
#include <sched.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
_Atomic_word a_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex(): a_(0)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
while( __exchange_and_add(&m_.a_, 1) )
|
||||
{
|
||||
__atomic_add(&m_.a_, -1);
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
__atomic_add(&m_.a_, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
|
73
include/boost/detail/lwm_irix.hpp
Normal file
73
include/boost/detail/lwm_irix.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/lwm_irix.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2002 Dan Gohman
|
||||
//
|
||||
// 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 <sgidefs.h>
|
||||
#include <mutex.h>
|
||||
#include <sched.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
__uint32_t l_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex(): l_(0)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
while( test_and_set32(&m_.l_, 1) )
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
m_.l_ = 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
|
84
include/boost/detail/lwm_linux.hpp
Normal file
84
include/boost/detail/lwm_linux.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/lwm_linux.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)
|
||||
//
|
||||
|
||||
//
|
||||
// This implementation uses <asm/atomic.h>. This is a kernel header;
|
||||
// using kernel headers in a user program may cause a number of problems,
|
||||
// and not all flavors of Linux provide the atomic instructions.
|
||||
//
|
||||
// This file is only provided because the performance of this implementation
|
||||
// is about 3.5 times higher than the pthreads version. Use at your own risk
|
||||
// (by defining BOOST_USE_ASM_ATOMIC_H.)
|
||||
//
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <sched.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
atomic_t a_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
atomic_t a = ATOMIC_INIT(1);
|
||||
a_ = a;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
while( !atomic_dec_and_test(&m_.a_) )
|
||||
{
|
||||
atomic_inc(&m_.a_);
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
atomic_inc(&m_.a_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
|
@@ -1,5 +1,5 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
#ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
@@ -34,4 +34,4 @@ public:
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
|
@@ -1,5 +1,5 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
#ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost
|
||||
@@ -43,15 +42,15 @@ public:
|
||||
// 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 );
|
||||
pthread_mutex_init(&m_, pthread_mutexattr_default);
|
||||
#else
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
|
||||
pthread_mutex_init(&m_, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
~lightweight_mutex()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
|
||||
pthread_mutex_destroy(&m_);
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
@@ -70,12 +69,12 @@ public:
|
||||
|
||||
scoped_lock(lightweight_mutex & m): m_(m.m_)
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
pthread_mutex_lock(&m_);
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
pthread_mutex_unlock(&m_);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -84,4 +83,4 @@ public:
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
122
include/boost/detail/lwm_win32.hpp
Normal file
122
include/boost/detail/lwm_win32.hpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_win32.hpp
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8027 // Functions containing while are not expanded inline
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
|
||||
|
||||
extern "C" long_type __cdecl _InterlockedExchange(long volatile *, long);
|
||||
|
||||
#pragma intrinsic(_InterlockedExchange)
|
||||
|
||||
inline long InterlockedExchange(long volatile* lp, long l)
|
||||
{
|
||||
return _InterlockedExchange(lp, l);
|
||||
}
|
||||
|
||||
#else // _WIN64
|
||||
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
|
||||
|
||||
#endif // _WIN64
|
||||
|
||||
extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
|
||||
|
||||
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
long l_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex(): l_(0)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
while( InterlockedExchange(&m_.l_, 1) )
|
||||
{
|
||||
// Note: changed to Sleep(1) from Sleep(0).
|
||||
// According to MSDN, Sleep(0) will never yield
|
||||
// to a lower-priority thread, whereas Sleep(1)
|
||||
// will. Performance seems not to be affected.
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
InterlockedExchange(&m_.l_, 0);
|
||||
|
||||
// Note: adding a yield here will make
|
||||
// the spinlock more fair and will increase the overall
|
||||
// performance of some applications substantially in
|
||||
// high contention situations, but will penalize the
|
||||
// low contention / single thread case up to 5x
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn .8027 // Functions containing while are not expanded inline
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
|
@@ -1,5 +1,5 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
#ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
@@ -11,15 +11,12 @@
|
||||
// boost/detail/lwm_win32_cs.hpp
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
// Copyright (c) Microsoft Corporation 2014
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/predef.h>
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
@@ -32,7 +29,7 @@ namespace detail
|
||||
|
||||
#ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
struct critical_section
|
||||
struct CRITICAL_SECTION
|
||||
{
|
||||
struct critical_section_debug * DebugInfo;
|
||||
long LockCount;
|
||||
@@ -46,18 +43,10 @@ struct critical_section
|
||||
#endif
|
||||
};
|
||||
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(critical_section *, unsigned long, unsigned long);
|
||||
#else
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
|
||||
#endif
|
||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
|
||||
|
||||
#else
|
||||
|
||||
typedef ::CRITICAL_SECTION critical_section;
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *);
|
||||
|
||||
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
@@ -65,7 +54,7 @@ class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
critical_section cs_;
|
||||
CRITICAL_SECTION cs_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
@@ -74,11 +63,7 @@ public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
InitializeCriticalSectionEx(&cs_, 4000, 0);
|
||||
#else
|
||||
InitializeCriticalSection(&cs_);
|
||||
#endif
|
||||
}
|
||||
|
||||
~lightweight_mutex()
|
||||
@@ -116,4 +101,4 @@ public:
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
63
include/boost/detail/lwm_win32_nt.hpp
Normal file
63
include/boost/detail/lwm_win32_nt.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef BOOST_DETAIL_LWM_WIN32_NT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_WIN32_NT_HPP_INCLUDED
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_win32_nt.hpp
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// "No threads" version of lwm_win32.hpp; binary compatible but no-op.
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
long l_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex(): l_(0)
|
||||
{
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock(lightweight_mutex &)
|
||||
{
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_NT_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
|
151
include/boost/detail/shared_array_nmt.hpp
Normal file
151
include/boost/detail/shared_array_nmt.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/shared_array_nmt.hpp - shared_array.hpp without member templates
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <algorithm> // for std::swap
|
||||
#include <functional> // for std::less
|
||||
#include <new> // for std::bad_alloc
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class shared_array
|
||||
{
|
||||
private:
|
||||
|
||||
typedef detail::atomic_count count_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit shared_array(T * p = 0): px(p)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try // prevent leak if new throws
|
||||
{
|
||||
pn = new count_type(1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::checked_array_delete(p);
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pn = new count_type(1);
|
||||
|
||||
if(pn == 0)
|
||||
{
|
||||
boost::checked_array_delete(p);
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
~shared_array()
|
||||
{
|
||||
if(--*pn == 0)
|
||||
{
|
||||
boost::checked_array_delete(px);
|
||||
delete pn;
|
||||
}
|
||||
}
|
||||
|
||||
shared_array(shared_array const & r) : px(r.px) // never throws
|
||||
{
|
||||
pn = r.pn;
|
||||
++*pn;
|
||||
}
|
||||
|
||||
shared_array & operator=(shared_array const & r)
|
||||
{
|
||||
shared_array(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset(T * p = 0)
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != px);
|
||||
shared_array(p).swap(*this);
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
T & operator[](std::ptrdiff_t i) const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
BOOST_ASSERT(i >= 0);
|
||||
return px[i];
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
{
|
||||
return *pn;
|
||||
}
|
||||
|
||||
bool unique() const // never throws
|
||||
{
|
||||
return *pn == 1;
|
||||
}
|
||||
|
||||
void swap(shared_array<T> & other) // never throws
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
std::swap(pn, other.pn);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * px; // contained pointer
|
||||
count_type * pn; // ptr to reference counter
|
||||
|
||||
}; // shared_array
|
||||
|
||||
template<class T, class U> inline bool operator==(shared_array<T> const & a, shared_array<U> const & b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(shared_array<T> const & a, shared_array<U> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b)
|
||||
{
|
||||
return std::less<T*>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
|
558
include/boost/detail/shared_count.hpp
Normal file
558
include/boost/detail/shared_count.hpp
Normal file
@@ -0,0 +1,558 @@
|
||||
#ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||
#define BOOST_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.
|
||||
//
|
||||
// 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/throw_exception.hpp>
|
||||
#include <boost/detail/lightweight_mutex.hpp>
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
#include <boost/detail/quick_allocator.hpp>
|
||||
#endif
|
||||
|
||||
#include <memory> // std::auto_ptr, std::allocator
|
||||
#include <functional> // std::less
|
||||
#include <exception> // std::exception
|
||||
#include <new> // std::bad_alloc
|
||||
#include <typeinfo> // std::type_info in get_deleter
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
|
||||
# pragma warn -8027 // Functions containing try are not expanded inline
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Debug hooks
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn);
|
||||
void sp_array_constructor_hook(void * px);
|
||||
void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn);
|
||||
void sp_array_destructor_hook(void * px);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// The standard library that comes with Borland C++ 5.5.1
|
||||
// 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. The version
|
||||
// check is deliberately conservative.
|
||||
|
||||
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
|
||||
# pragma option push -pc
|
||||
#endif
|
||||
|
||||
class bad_weak_ptr: public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
virtual char const * what() const throw()
|
||||
{
|
||||
return "boost::bad_weak_ptr";
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
|
||||
# pragma option pop
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
typedef detail::lightweight_mutex mutex_type;
|
||||
|
||||
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
|
||||
|
||||
// destruct() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destruct() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter(std::type_info const & ti) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
mutex_type::scoped_lock lock(mtx_);
|
||||
#endif
|
||||
++use_count_;
|
||||
}
|
||||
|
||||
void add_ref_lock()
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
mutex_type::scoped_lock lock(mtx_);
|
||||
#endif
|
||||
if(use_count_ == 0) boost::throw_exception(boost::bad_weak_ptr());
|
||||
++use_count_;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
mutex_type::scoped_lock lock(mtx_);
|
||||
#endif
|
||||
long new_use_count = --use_count_;
|
||||
|
||||
if(new_use_count != 0) return;
|
||||
}
|
||||
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
mutex_type::scoped_lock lock(mtx_);
|
||||
#endif
|
||||
++weak_count_;
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
long new_weak_count;
|
||||
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
mutex_type::scoped_lock lock(mtx_);
|
||||
#endif
|
||||
new_weak_count = --weak_count_;
|
||||
}
|
||||
|
||||
if(new_weak_count == 0)
|
||||
{
|
||||
destruct();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
mutex_type::scoped_lock lock(mtx_);
|
||||
#endif
|
||||
return use_count_;
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
#if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32)
|
||||
mutable mutex_type mtx_;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
|
||||
{
|
||||
boost::sp_scalar_constructor_hook(px, sizeof(T), pn);
|
||||
}
|
||||
|
||||
template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
|
||||
{
|
||||
boost::sp_array_constructor_hook(px);
|
||||
}
|
||||
|
||||
template<class P, class D> void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
|
||||
{
|
||||
boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
|
||||
}
|
||||
|
||||
template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
|
||||
{
|
||||
boost::sp_array_destructor_hook(px);
|
||||
}
|
||||
|
||||
template<class P, class D> void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// Borland's Codeguard trips up over the -Vx- option here:
|
||||
//
|
||||
#ifdef __CODEGUARD__
|
||||
# pragma option push -Vx-
|
||||
#endif
|
||||
|
||||
template<class P, class D> class sp_counted_base_impl: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
P ptr; // copy constructor must not throw
|
||||
D del; // copy constructor must not throw
|
||||
|
||||
sp_counted_base_impl(sp_counted_base_impl const &);
|
||||
sp_counted_base_impl & operator= (sp_counted_base_impl const &);
|
||||
|
||||
typedef sp_counted_base_impl<P, D> this_type;
|
||||
|
||||
public:
|
||||
|
||||
// pre: initial_use_count <= initial_weak_count, d(p) must not throw
|
||||
|
||||
sp_counted_base_impl(P p, D d): ptr(p), del(d)
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
detail::cbi_call_constructor_hook(this, p, d, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
detail::cbi_call_destructor_hook(this, ptr, del, 0);
|
||||
#endif
|
||||
del(ptr);
|
||||
}
|
||||
|
||||
virtual void * get_deleter(std::type_info const & ti)
|
||||
{
|
||||
return ti == typeid(D)? &del: 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
|
||||
};
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
int const shared_count_id = 0x2C35F101;
|
||||
int const weak_count_id = 0x298C38A4;
|
||||
|
||||
#endif
|
||||
|
||||
class weak_count;
|
||||
|
||||
class shared_count
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base * pi_;
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
int id_;
|
||||
#endif
|
||||
|
||||
friend class weak_count;
|
||||
|
||||
public:
|
||||
|
||||
shared_count(): pi_(0) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
template<class P, class D> shared_count(P p, D d): pi_(0)
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_base_impl<P, D>(p, d);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
d(p); // delete p
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_base_impl<P, D>(p, d);
|
||||
|
||||
if(pi_ == 0)
|
||||
{
|
||||
d(p); // delete p
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#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_base_impl< Y *, checked_deleter<Y> >(r.get(), checked_deleter<Y>()))
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
r.release();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
~shared_count() // nothrow
|
||||
{
|
||||
if(pi_ != 0) pi_->release();
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
id_ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
shared_count(shared_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if(pi_ != 0) pi_->add_ref_copy();
|
||||
}
|
||||
|
||||
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
||||
|
||||
shared_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if(tmp != pi_)
|
||||
{
|
||||
if(tmp != 0) tmp->add_ref_copy();
|
||||
if(pi_ != 0) pi_->release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(shared_count & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
r.pi_ = pi_;
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return pi_ != 0? pi_->use_count(): 0;
|
||||
}
|
||||
|
||||
bool unique() const // nothrow
|
||||
{
|
||||
return use_count() == 1;
|
||||
}
|
||||
|
||||
friend inline bool operator==(shared_count const & a, shared_count const & b)
|
||||
{
|
||||
return a.pi_ == b.pi_;
|
||||
}
|
||||
|
||||
friend inline bool operator<(shared_count const & a, shared_count const & b)
|
||||
{
|
||||
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
|
||||
}
|
||||
|
||||
void * get_deleter(std::type_info const & ti) const
|
||||
{
|
||||
return pi_? pi_->get_deleter(ti): 0;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __CODEGUARD__
|
||||
# pragma option pop
|
||||
#endif
|
||||
|
||||
|
||||
class weak_count
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base * pi_;
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
int id_;
|
||||
#endif
|
||||
|
||||
friend class shared_count;
|
||||
|
||||
public:
|
||||
|
||||
weak_count(): pi_(0) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
weak_count(shared_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_add_ref();
|
||||
}
|
||||
|
||||
weak_count(weak_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_add_ref();
|
||||
}
|
||||
|
||||
~weak_count() // nothrow
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
id_ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
weak_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
weak_count & operator= (weak_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(weak_count & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
r.pi_ = pi_;
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return pi_ != 0? pi_->use_count(): 0;
|
||||
}
|
||||
|
||||
friend inline bool operator==(weak_count const & a, weak_count const & b)
|
||||
{
|
||||
return a.pi_ == b.pi_;
|
||||
}
|
||||
|
||||
friend inline bool operator<(weak_count const & a, weak_count const & b)
|
||||
{
|
||||
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
|
||||
}
|
||||
};
|
||||
|
||||
inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if(pi_ != 0)
|
||||
{
|
||||
pi_->add_ref_lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::throw_exception(boost::bad_weak_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn .8027 // Functions containing try are not expanded inline
|
||||
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
182
include/boost/detail/shared_ptr_nmt.hpp
Normal file
182
include/boost/detail/shared_ptr_nmt.hpp
Normal file
@@ -0,0 +1,182 @@
|
||||
#ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
# include <memory> // for std::auto_ptr
|
||||
#endif
|
||||
|
||||
#include <algorithm> // for std::swap
|
||||
#include <functional> // for std::less
|
||||
#include <new> // for std::bad_alloc
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class shared_ptr
|
||||
{
|
||||
private:
|
||||
|
||||
typedef detail::atomic_count count_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
typedef T value_type;
|
||||
|
||||
explicit shared_ptr(T * p = 0): px(p)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try // prevent leak if new throws
|
||||
{
|
||||
pn = new count_type(1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::checked_delete(p);
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pn = new count_type(1);
|
||||
|
||||
if(pn == 0)
|
||||
{
|
||||
boost::checked_delete(p);
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
~shared_ptr()
|
||||
{
|
||||
if(--*pn == 0)
|
||||
{
|
||||
boost::checked_delete(px);
|
||||
delete pn;
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr(shared_ptr const & r): px(r.px) // never throws
|
||||
{
|
||||
pn = r.pn;
|
||||
++*pn;
|
||||
}
|
||||
|
||||
shared_ptr & operator=(shared_ptr const & r)
|
||||
{
|
||||
shared_ptr(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
explicit shared_ptr(std::auto_ptr<T> & r)
|
||||
{
|
||||
pn = new count_type(1); // may throw
|
||||
px = r.release(); // fix: moved here to stop leak if new throws
|
||||
}
|
||||
|
||||
shared_ptr & operator=(std::auto_ptr<T> & r)
|
||||
{
|
||||
shared_ptr(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void reset(T * p = 0)
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != px);
|
||||
shared_ptr(p).swap(*this);
|
||||
}
|
||||
|
||||
T & operator*() const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
return *px;
|
||||
}
|
||||
|
||||
T * operator->() const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
return px;
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
{
|
||||
return *pn;
|
||||
}
|
||||
|
||||
bool unique() const // never throws
|
||||
{
|
||||
return *pn == 1;
|
||||
}
|
||||
|
||||
void swap(shared_ptr<T> & other) // never throws
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
std::swap(pn, other.pn);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * px; // contained pointer
|
||||
count_type * pn; // ptr to reference counter
|
||||
};
|
||||
|
||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
|
||||
{
|
||||
return std::less<T*>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
|
||||
|
||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
@@ -6,13 +6,62 @@
|
||||
//
|
||||
// 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
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_this.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class enable_shared_from_this
|
||||
{
|
||||
protected:
|
||||
|
||||
enable_shared_from_this()
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this(enable_shared_from_this const &)
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this & operator=(enable_shared_from_this const &)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~enable_shared_from_this()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
shared_ptr<T> shared_from_this()
|
||||
{
|
||||
shared_ptr<T> p(_internal_weak_this);
|
||||
BOOST_ASSERT(p.get() == this);
|
||||
return p;
|
||||
}
|
||||
|
||||
shared_ptr<T const> shared_from_this() const
|
||||
{
|
||||
shared_ptr<T const> p(_internal_weak_this);
|
||||
BOOST_ASSERT(p.get() == this);
|
||||
return p;
|
||||
}
|
||||
|
||||
typedef T _internal_element_type; // for bcc 5.5.1
|
||||
mutable weak_ptr<_internal_element_type> _internal_weak_this;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
|
29
include/boost/get_pointer.hpp
Normal file
29
include/boost/get_pointer.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright Peter Dimov and David Abrahams 2002.
|
||||
// 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 GET_POINTER_DWA20021219_HPP
|
||||
# define GET_POINTER_DWA20021219_HPP
|
||||
|
||||
# include <memory>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// get_pointer(p) extracts a ->* capable pointer from p
|
||||
|
||||
template<class T> T * get_pointer(T * p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
// get_pointer(shared_ptr<T> const & p) has been moved to shared_ptr.hpp
|
||||
|
||||
template<class T> T * get_pointer(std::auto_ptr<T> const& p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // GET_POINTER_DWA20021219_HPP
|
@@ -6,13 +6,267 @@
|
||||
//
|
||||
// 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
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4284) // odd return type for operator->
|
||||
#endif
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <functional> // for std::less
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//
|
||||
// intrusive_ptr
|
||||
//
|
||||
// A smart pointer that uses intrusive reference counting.
|
||||
//
|
||||
// Relies on unqualified calls to
|
||||
//
|
||||
// void intrusive_ptr_add_ref(T * p);
|
||||
// void intrusive_ptr_release(T * p);
|
||||
//
|
||||
// (p != 0)
|
||||
//
|
||||
// The object is responsible for destroying itself.
|
||||
//
|
||||
|
||||
template<class T> class intrusive_ptr
|
||||
{
|
||||
private:
|
||||
|
||||
typedef intrusive_ptr this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
intrusive_ptr(): p_(0)
|
||||
{
|
||||
}
|
||||
|
||||
intrusive_ptr(T * p, bool add_ref = true): p_(p)
|
||||
{
|
||||
if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
|
||||
{
|
||||
if(p_ != 0) intrusive_ptr_add_ref(p_);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
|
||||
{
|
||||
if(p_ != 0) intrusive_ptr_add_ref(p_);
|
||||
}
|
||||
|
||||
~intrusive_ptr()
|
||||
{
|
||||
if(p_ != 0) intrusive_ptr_release(p_);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
intrusive_ptr & operator=(intrusive_ptr const & rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
intrusive_ptr & operator=(T * rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T * get() const
|
||||
{
|
||||
return p_;
|
||||
}
|
||||
|
||||
T & operator*() const
|
||||
{
|
||||
return *p_;
|
||||
}
|
||||
|
||||
T * operator->() const
|
||||
{
|
||||
return p_;
|
||||
}
|
||||
|
||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
|
||||
|
||||
operator bool () const
|
||||
{
|
||||
return p_ != 0;
|
||||
}
|
||||
|
||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return p_ == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef T * this_type::*unspecified_bool_type;
|
||||
|
||||
operator unspecified_bool_type () const
|
||||
{
|
||||
return p_ == 0? 0: &this_type::p_;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// operator! is a Borland-specific workaround
|
||||
bool operator! () const
|
||||
{
|
||||
return p_ == 0;
|
||||
}
|
||||
|
||||
void swap(intrusive_ptr & rhs)
|
||||
{
|
||||
T * tmp = p_;
|
||||
p_ = rhs.p_;
|
||||
rhs.p_ = tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * p_;
|
||||
};
|
||||
|
||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
|
||||
{
|
||||
return a.get() == b;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
|
||||
{
|
||||
return a.get() != b;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return a == b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return a != b.get();
|
||||
}
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
|
||||
|
||||
// Resolve the ambiguity between our op!= and the one in rel_ops
|
||||
|
||||
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return std::less<T *>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
// mem_fn support
|
||||
|
||||
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return static_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return const_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return dynamic_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
// operator<<
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
|
||||
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
|
||||
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
|
||||
using std::basic_ostream;
|
||||
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
|
||||
# else
|
||||
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
|
||||
# endif
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
|
@@ -1,17 +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/make_shared.html
|
||||
// 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,121 +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>
|
||||
|
||||
namespace boost {
|
||||
|
||||
//static_pointer_cast overload for raw pointers
|
||||
template<class T, class U>
|
||||
inline T* static_pointer_cast(U *ptr)
|
||||
{
|
||||
return static_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
//dynamic_pointer_cast overload for raw pointers
|
||||
template<class T, class U>
|
||||
inline T* dynamic_pointer_cast(U *ptr)
|
||||
{
|
||||
return dynamic_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
//const_pointer_cast overload for raw pointers
|
||||
template<class T, class U>
|
||||
inline T* const_pointer_cast(U *ptr)
|
||||
{
|
||||
return const_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
//reinterpret_pointer_cast overload for raw pointers
|
||||
template<class T, class U>
|
||||
inline T* reinterpret_pointer_cast(U *ptr)
|
||||
{
|
||||
return reinterpret_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#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_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_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_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_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_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/pointer_to_other.html
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Defines the same pointer type (raw or smart) to another pointee type
|
||||
|
||||
template<class T, class U>
|
||||
struct pointer_to_other;
|
||||
|
||||
template<class T, class U,
|
||||
template<class> class Sp>
|
||||
struct pointer_to_other< Sp<T>, U >
|
||||
{
|
||||
typedef Sp<U> type;
|
||||
};
|
||||
|
||||
template<class T, class T2, class U,
|
||||
template<class, class> class Sp>
|
||||
struct pointer_to_other< Sp<T, T2>, U >
|
||||
{
|
||||
typedef Sp<U, T2> type;
|
||||
};
|
||||
|
||||
template<class T, class T2, class T3, class U,
|
||||
template<class, class, class> class Sp>
|
||||
struct pointer_to_other< Sp<T, T2, T3>, U >
|
||||
{
|
||||
typedef Sp<U, T2, T3> type;
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
struct pointer_to_other< T*, U >
|
||||
{
|
||||
typedef U* type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
|
@@ -11,6 +11,125 @@
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/scoped_array.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/config.hpp> // in case ptrdiff_t not in std
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Debug hooks
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
void sp_array_constructor_hook(void * p);
|
||||
void sp_array_destructor_hook(void * p);
|
||||
|
||||
#endif
|
||||
|
||||
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
|
||||
// is guaranteed, either on destruction of the scoped_array or via an explicit
|
||||
// reset(). Use shared_array or std::vector if your needs are more complex.
|
||||
|
||||
template<class T> class scoped_array // noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
T * ptr;
|
||||
|
||||
scoped_array(scoped_array const &);
|
||||
scoped_array & operator=(scoped_array const &);
|
||||
|
||||
typedef scoped_array<T> this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_array(T * p = 0) : ptr(p) // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_array_constructor_hook(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
~scoped_array() // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_array_destructor_hook(ptr);
|
||||
#endif
|
||||
boost::checked_array_delete(ptr);
|
||||
}
|
||||
|
||||
void reset(T * p = 0) // never throws
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors
|
||||
this_type(p).swap(*this);
|
||||
}
|
||||
|
||||
T & operator[](std::ptrdiff_t i) const // never throws
|
||||
{
|
||||
BOOST_ASSERT(ptr != 0);
|
||||
BOOST_ASSERT(i >= 0);
|
||||
return ptr[i];
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
|
||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
|
||||
|
||||
operator bool () const
|
||||
{
|
||||
return ptr != 0;
|
||||
}
|
||||
|
||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return ptr == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef T * this_type::*unspecified_bool_type;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return ptr == 0? 0: &this_type::ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool operator! () const // never throws
|
||||
{
|
||||
return ptr == 0;
|
||||
}
|
||||
|
||||
void swap(scoped_array & b) // never throws
|
||||
{
|
||||
T * tmp = b.ptr;
|
||||
b.ptr = ptr;
|
||||
ptr = tmp;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
||||
|
@@ -11,6 +11,147 @@
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/scoped_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
# include <memory> // for std::auto_ptr
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Debug hooks
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
void sp_scalar_constructor_hook(void * p);
|
||||
void sp_scalar_destructor_hook(void * p);
|
||||
|
||||
#endif
|
||||
|
||||
// scoped_ptr mimics a built-in pointer except that it guarantees deletion
|
||||
// of the object pointed to, either on destruction of the scoped_ptr or via
|
||||
// an explicit reset(). scoped_ptr is a simple solution for simple needs;
|
||||
// use shared_ptr or std::auto_ptr if your needs are more complex.
|
||||
|
||||
template<class T> class scoped_ptr // noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
T * ptr;
|
||||
|
||||
scoped_ptr(scoped_ptr const &);
|
||||
scoped_ptr & operator=(scoped_ptr const &);
|
||||
|
||||
typedef scoped_ptr<T> this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_ptr(T * p = 0): ptr(p) // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
explicit scoped_ptr(std::auto_ptr<T> p): ptr(p.release()) // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
~scoped_ptr() // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_destructor_hook(ptr);
|
||||
#endif
|
||||
boost::checked_delete(ptr);
|
||||
}
|
||||
|
||||
void reset(T * p = 0) // never throws
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors
|
||||
this_type(p).swap(*this);
|
||||
}
|
||||
|
||||
T & operator*() const // never throws
|
||||
{
|
||||
BOOST_ASSERT(ptr != 0);
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
T * operator->() const // never throws
|
||||
{
|
||||
BOOST_ASSERT(ptr != 0);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
|
||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
|
||||
|
||||
operator bool () const
|
||||
{
|
||||
return ptr != 0;
|
||||
}
|
||||
|
||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return ptr == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
typedef T * this_type::*unspecified_bool_type;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return ptr == 0? 0: &this_type::ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool operator! () const // never throws
|
||||
{
|
||||
return ptr == 0;
|
||||
}
|
||||
|
||||
void swap(scoped_ptr & b) // never throws
|
||||
{
|
||||
T * tmp = b.ptr;
|
||||
b.ptr = ptr;
|
||||
ptr = tmp;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// get_pointer(p) is a generic way to say p.get()
|
||||
|
||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
|
||||
|
@@ -14,6 +14,162 @@
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/shared_array.hpp>
|
||||
#include <boost/config.hpp> // for broken compiler workarounds
|
||||
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
#include <boost/detail/shared_array_nmt.hpp>
|
||||
#else
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
|
||||
#include <boost/detail/shared_count.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <algorithm> // for std::swap
|
||||
#include <functional> // for std::less
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//
|
||||
// shared_array
|
||||
//
|
||||
// shared_array extends shared_ptr to arrays.
|
||||
// The array pointed to is deleted when the last shared_array pointing to it
|
||||
// is destroyed or reset.
|
||||
//
|
||||
|
||||
template<class T> class shared_array
|
||||
{
|
||||
private:
|
||||
|
||||
// Borland 5.5.1 specific workarounds
|
||||
typedef checked_array_deleter<T> deleter;
|
||||
typedef shared_array<T> this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit shared_array(T * p = 0): px(p), pn(p, deleter())
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Requirements: D's copy constructor must not throw
|
||||
//
|
||||
// shared_array will release p by calling d(p)
|
||||
//
|
||||
|
||||
template<class D> shared_array(T * p, D d): px(p), pn(p, d)
|
||||
{
|
||||
}
|
||||
|
||||
// generated copy constructor, assignment, destructor are fine
|
||||
|
||||
void reset(T * p = 0)
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != px);
|
||||
this_type(p).swap(*this);
|
||||
}
|
||||
|
||||
template <class D> void reset(T * p, D d)
|
||||
{
|
||||
this_type(p, d).swap(*this);
|
||||
}
|
||||
|
||||
T & operator[] (std::ptrdiff_t i) const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
BOOST_ASSERT(i >= 0);
|
||||
return px[i];
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
|
||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
|
||||
|
||||
operator bool () const
|
||||
{
|
||||
return px != 0;
|
||||
}
|
||||
|
||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return px == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef T * this_type::*unspecified_bool_type;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return px == 0? 0: &this_type::px;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool operator! () const // never throws
|
||||
{
|
||||
return px == 0;
|
||||
}
|
||||
|
||||
bool unique() const // never throws
|
||||
{
|
||||
return pn.unique();
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
{
|
||||
return pn.use_count();
|
||||
}
|
||||
|
||||
void swap(shared_array<T> & other) // never throws
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
pn.swap(other.pn);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * px; // contained pointer
|
||||
detail::shared_count pn; // reference counter
|
||||
|
||||
}; // shared_array
|
||||
|
||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
||||
{
|
||||
return std::less<T*>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
#endif // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
|
||||
|
@@ -5,7 +5,7 @@
|
||||
// shared_ptr.hpp
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001-2008 Peter Dimov
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -14,6 +14,460 @@
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/config.hpp> // for broken compiler workarounds
|
||||
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
#include <boost/detail/shared_ptr_nmt.hpp>
|
||||
#else
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/detail/shared_count.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <memory> // for std::auto_ptr
|
||||
#include <algorithm> // for std::swap
|
||||
#include <functional> // for std::less
|
||||
#include <typeinfo> // for std::bad_cast
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
|
||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4284) // odd return type for operator->
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class weak_ptr;
|
||||
template<class T> class enable_shared_from_this;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct static_cast_tag {};
|
||||
struct const_cast_tag {};
|
||||
struct dynamic_cast_tag {};
|
||||
struct polymorphic_cast_tag {};
|
||||
|
||||
template<class T> struct shared_ptr_traits
|
||||
{
|
||||
typedef T & reference;
|
||||
};
|
||||
|
||||
template<> struct shared_ptr_traits<void>
|
||||
{
|
||||
typedef void reference;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
|
||||
|
||||
template<> struct shared_ptr_traits<void const>
|
||||
{
|
||||
typedef void reference;
|
||||
};
|
||||
|
||||
template<> struct shared_ptr_traits<void volatile>
|
||||
{
|
||||
typedef void reference;
|
||||
};
|
||||
|
||||
template<> struct shared_ptr_traits<void const volatile>
|
||||
{
|
||||
typedef void reference;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// enable_shared_from_this support
|
||||
|
||||
template<class T, class Y> void sp_enable_shared_from_this( shared_count const & pn, boost::enable_shared_from_this<T> const * pe, Y const * px )
|
||||
{
|
||||
if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
|
||||
}
|
||||
|
||||
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
//
|
||||
// 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<class T> class shared_ptr
|
||||
{
|
||||
private:
|
||||
|
||||
// Borland 5.5.1 specific workaround
|
||||
typedef shared_ptr<T> this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef typename detail::shared_ptr_traits<T>::reference reference;
|
||||
|
||||
shared_ptr(): px(0), pn() // never throws in 1.30+
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete
|
||||
{
|
||||
detail::sp_enable_shared_from_this( pn, p, p );
|
||||
}
|
||||
|
||||
//
|
||||
// Requirements: D's copy constructor must not throw
|
||||
//
|
||||
// shared_ptr will release p by calling d(p)
|
||||
//
|
||||
|
||||
template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
|
||||
{
|
||||
detail::sp_enable_shared_from_this( pn, p, p );
|
||||
}
|
||||
|
||||
// generated copy constructor, assignment, destructor are fine...
|
||||
|
||||
// except that Borland C++ has a bug, and g++ with -Wsynth warns
|
||||
#if defined(__BORLANDC__) || defined(__GNUC__)
|
||||
|
||||
shared_ptr & operator=(shared_ptr const & r) // never throws
|
||||
{
|
||||
px = r.px;
|
||||
pn = r.pn; // shared_count::op= doesn't throw
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y>
|
||||
explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
|
||||
{
|
||||
// it is now safe to copy r.px, as pn(r.pn) did not throw
|
||||
px = r.px;
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r, detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
||||
{
|
||||
if(px == 0) // need to allocate new counter -- the cast failed
|
||||
{
|
||||
pn = detail::shared_count();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
||||
{
|
||||
if(px == 0)
|
||||
{
|
||||
boost::throw_exception(std::bad_cast());
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
template<class Y>
|
||||
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
|
||||
{
|
||||
Y * tmp = r.get();
|
||||
pn = detail::shared_count(r);
|
||||
detail::sp_enable_shared_from_this( pn, tmp, tmp );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
|
||||
|
||||
template<class Y>
|
||||
shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
|
||||
{
|
||||
px = r.px;
|
||||
pn = r.pn; // shared_count::op= doesn't throw
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
template<class Y>
|
||||
shared_ptr & operator=(std::auto_ptr<Y> & r)
|
||||
{
|
||||
this_type(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void reset() // never throws in 1.30+
|
||||
{
|
||||
this_type().swap(*this);
|
||||
}
|
||||
|
||||
template<class Y> void reset(Y * p) // Y must be complete
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
|
||||
this_type(p).swap(*this);
|
||||
}
|
||||
|
||||
template<class Y, class D> void reset(Y * p, D d)
|
||||
{
|
||||
this_type(p, d).swap(*this);
|
||||
}
|
||||
|
||||
reference operator* () const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
return *px;
|
||||
}
|
||||
|
||||
T * operator-> () const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
return px;
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
|
||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
|
||||
|
||||
operator bool () const
|
||||
{
|
||||
return px != 0;
|
||||
}
|
||||
|
||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return px == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef T * this_type::*unspecified_bool_type;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return px == 0? 0: &this_type::px;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// operator! is redundant, but some compilers need it
|
||||
|
||||
bool operator! () const // never throws
|
||||
{
|
||||
return px == 0;
|
||||
}
|
||||
|
||||
bool unique() const // never throws
|
||||
{
|
||||
return pn.unique();
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
{
|
||||
return pn.use_count();
|
||||
}
|
||||
|
||||
void swap(shared_ptr<T> & other) // never throws
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
pn.swap(other.pn);
|
||||
}
|
||||
|
||||
template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
|
||||
{
|
||||
return pn < rhs.pn;
|
||||
}
|
||||
|
||||
void * _internal_get_deleter(std::type_info const & ti) const
|
||||
{
|
||||
return pn.get_deleter(ti);
|
||||
}
|
||||
|
||||
// Tasteless as this may seem, making all members public allows member templates
|
||||
// to work in the absence of member template friends. (Matthew Langston)
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
|
||||
private:
|
||||
|
||||
template<class Y> friend class shared_ptr;
|
||||
template<class Y> friend class weak_ptr;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
T * px; // contained pointer
|
||||
detail::shared_count pn; // reference counter
|
||||
|
||||
}; // shared_ptr
|
||||
|
||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
|
||||
|
||||
// Resolve the ambiguity between our op!= and the one in rel_ops
|
||||
|
||||
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
{
|
||||
return a._internal_less(b);
|
||||
}
|
||||
|
||||
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
|
||||
{
|
||||
return shared_ptr<T>(r, detail::static_cast_tag());
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
|
||||
{
|
||||
return shared_ptr<T>(r, detail::const_cast_tag());
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
|
||||
{
|
||||
return shared_ptr<T>(r, detail::dynamic_cast_tag());
|
||||
}
|
||||
|
||||
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
|
||||
|
||||
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
|
||||
{
|
||||
return shared_ptr<T>(r, detail::static_cast_tag());
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
|
||||
{
|
||||
return shared_ptr<T>(r, detail::dynamic_cast_tag());
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
|
||||
{
|
||||
return shared_ptr<T>(r, detail::polymorphic_cast_tag());
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
|
||||
{
|
||||
BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
|
||||
return shared_static_cast<T>(r);
|
||||
}
|
||||
|
||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
|
||||
|
||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
// operator<<
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
|
||||
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
|
||||
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
|
||||
using std::basic_ostream;
|
||||
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
|
||||
# else
|
||||
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
|
||||
# endif
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// get_deleter (experimental)
|
||||
|
||||
#if (defined(__GNUC__) && (__GNUC__ < 3)) || (defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238))
|
||||
|
||||
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
|
||||
// apparently EDG 2.38 also doesn't accept it
|
||||
|
||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
{
|
||||
void const * q = p._internal_get_deleter(typeid(D));
|
||||
return const_cast<D *>(static_cast<D const *>(q));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
{
|
||||
return static_cast<D *>(p._internal_get_deleter(typeid(D)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
#endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
|
||||
|
@@ -1,6 +1,3 @@
|
||||
#ifndef BOOST_SMART_PTR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// smart_ptr.hpp
|
||||
//
|
||||
@@ -25,7 +22,4 @@
|
||||
# include <boost/weak_ptr.hpp>
|
||||
# include <boost/intrusive_ptr.hpp>
|
||||
# include <boost/enable_shared_from_this.hpp>
|
||||
# include <boost/make_shared.hpp>
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,68 +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 <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(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
#endif
|
||||
|
||||
class bad_weak_ptr: public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
virtual char const * what() const throw()
|
||||
{
|
||||
return "tr1::bad_weak_ptr";
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__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,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,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,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_NOEXCEPT
|
||||
{
|
||||
return px != 0;
|
||||
}
|
||||
|
||||
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
|
||||
|
||||
operator bool () const BOOST_NOEXCEPT
|
||||
{
|
||||
return px != 0;
|
||||
}
|
||||
|
||||
#elif defined( _MANAGED )
|
||||
|
||||
static void unspecified_bool( this_type*** )
|
||||
{
|
||||
}
|
||||
|
||||
typedef void (*unspecified_bool_type)( this_type*** );
|
||||
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: unspecified_bool;
|
||||
}
|
||||
|
||||
#elif \
|
||||
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
|
||||
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
|
||||
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
|
||||
|
||||
typedef element_type * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef element_type * this_type::*unspecified_bool_type;
|
||||
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: &this_type::px;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// operator! is redundant, but some compilers need it
|
||||
bool operator! () const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0;
|
||||
}
|
@@ -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,655 +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/detail/workaround.hpp>
|
||||
// In order to avoid circular dependencies with Boost.TR1
|
||||
// we make sure that our include of <memory> doesn't try to
|
||||
// pull in the TR1 headers: that's why we use this header
|
||||
// rather than including <memory> directly:
|
||||
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
||||
#include <functional> // std::less
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
# include <new> // std::bad_alloc
|
||||
#endif
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace movelib
|
||||
{
|
||||
|
||||
template< class T, class D > class unique_ptr;
|
||||
|
||||
} // namespace movelib
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
int const shared_count_id = 0x2C35F101;
|
||||
int const weak_count_id = 0x298C38A4;
|
||||
|
||||
#endif
|
||||
|
||||
struct sp_nothrow_tag {};
|
||||
|
||||
template< class D > struct sp_inplace_tag
|
||||
{
|
||||
};
|
||||
|
||||
template< class T > class sp_reference_wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Y > void operator()( Y * p ) const
|
||||
{
|
||||
(*t_)( p );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * t_;
|
||||
};
|
||||
|
||||
template< class D > struct sp_convert_reference
|
||||
{
|
||||
typedef D type;
|
||||
};
|
||||
|
||||
template< class D > struct sp_convert_reference< D& >
|
||||
{
|
||||
typedef sp_reference_wrapper< D > type;
|
||||
};
|
||||
|
||||
class weak_count;
|
||||
|
||||
class shared_count
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base * pi_;
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
int id_;
|
||||
#endif
|
||||
|
||||
friend class weak_count;
|
||||
|
||||
public:
|
||||
|
||||
shared_count(): pi_(0) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y> explicit shared_count( Y * p ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_p<Y>( p );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::checked_delete( p );
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_p<Y>( p );
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::checked_delete( p );
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
|
||||
template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
|
||||
#else
|
||||
template<class P, class D> shared_count( P p, D d ): pi_(0)
|
||||
#endif
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
|
||||
typedef Y* P;
|
||||
#endif
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_pd<P, D>(p, d);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
d(p); // delete p
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_pd<P, D>(p, d);
|
||||
|
||||
if(pi_ == 0)
|
||||
{
|
||||
d(p); // delete p
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||
|
||||
template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
pi_ = new sp_counted_impl_pd< P, D >( p );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
D::operator_fn( p ); // delete p
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pi_ = new sp_counted_impl_pd< P, D >( p );
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
D::operator_fn( p ); // delete p
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||
|
||||
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
typedef sp_counted_impl_pda<P, D, A> impl_type;
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
|
||||
|
||||
#else
|
||||
|
||||
typedef typename A::template rebind< impl_type >::other A2;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
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() // nothrow
|
||||
{
|
||||
if( pi_ != 0 ) pi_->release();
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
id_ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
shared_count(shared_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if( pi_ != 0 ) pi_->add_ref_copy();
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
shared_count(shared_count && r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
r.pi_ = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
||||
shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
|
||||
|
||||
shared_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if( tmp != 0 ) tmp->add_ref_copy();
|
||||
if( pi_ != 0 ) pi_->release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(shared_count & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
r.pi_ = pi_;
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return pi_ != 0? pi_->use_count(): 0;
|
||||
}
|
||||
|
||||
bool unique() const // nothrow
|
||||
{
|
||||
return use_count() == 1;
|
||||
}
|
||||
|
||||
bool empty() const // nothrow
|
||||
{
|
||||
return pi_ == 0;
|
||||
}
|
||||
|
||||
friend inline bool operator==(shared_count const & a, shared_count const & b)
|
||||
{
|
||||
return a.pi_ == b.pi_;
|
||||
}
|
||||
|
||||
friend inline bool operator<(shared_count const & a, shared_count const & b)
|
||||
{
|
||||
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
|
||||
}
|
||||
|
||||
void * get_deleter( sp_typeinfo const & ti ) const
|
||||
{
|
||||
return pi_? pi_->get_deleter( ti ): 0;
|
||||
}
|
||||
|
||||
void * get_untyped_deleter() const
|
||||
{
|
||||
return pi_? pi_->get_untyped_deleter(): 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class weak_count
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base * pi_;
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
int id_;
|
||||
#endif
|
||||
|
||||
friend class shared_count;
|
||||
|
||||
public:
|
||||
|
||||
weak_count(): pi_(0) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
weak_count(shared_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_add_ref();
|
||||
}
|
||||
|
||||
weak_count(weak_count const & r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_add_ref();
|
||||
}
|
||||
|
||||
// Move support
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
weak_count(weak_count && r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(weak_count_id)
|
||||
#endif
|
||||
{
|
||||
r.pi_ = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
~weak_count() // nothrow
|
||||
{
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
id_ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
weak_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
weak_count & operator= (weak_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(weak_count & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
r.pi_ = pi_;
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return pi_ != 0? pi_->use_count(): 0;
|
||||
}
|
||||
|
||||
bool empty() const // nothrow
|
||||
{
|
||||
return pi_ == 0;
|
||||
}
|
||||
|
||||
friend inline bool operator==(weak_count const & a, weak_count const & b)
|
||||
{
|
||||
return a.pi_ == b.pi_;
|
||||
}
|
||||
|
||||
friend inline bool operator<(weak_count const & a, weak_count const & b)
|
||||
{
|
||||
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
|
||||
}
|
||||
};
|
||||
|
||||
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if( pi_ == 0 || !pi_->add_ref_lock() )
|
||||
{
|
||||
boost::throw_exception( boost::bad_weak_ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if( pi_ != 0 && !pi_->add_ref_lock() )
|
||||
{
|
||||
pi_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn .8027 // Functions containing try are not expanded inline
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
@@ -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,151 +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 <machine/sys/inline.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
|
||||
if (1 == r)
|
||||
{
|
||||
_Asm_mf();
|
||||
}
|
||||
|
||||
return r - 1;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int v = *pw;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (0 == v)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
_Asm_mov_to_ar(_AREG_CCV,
|
||||
v,
|
||||
(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
|
||||
int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
|
||||
if (r == v)
|
||||
{
|
||||
return r + 1;
|
||||
}
|
||||
|
||||
v = r;
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
@@ -1,143 +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 <builtins.h>
|
||||
#include <sys/atomic_op.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int32_t* pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline int32_t atomic_decrement( int32_t * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int32_t originalValue;
|
||||
|
||||
__lwsync();
|
||||
originalValue = fetch_and_add( pw, -1 );
|
||||
__isync();
|
||||
|
||||
return (originalValue - 1);
|
||||
}
|
||||
|
||||
inline int32_t atomic_conditional_increment( int32_t * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int32_t tmp = fetch_and_add( pw, 0 );
|
||||
for( ;; )
|
||||
{
|
||||
if( tmp == 0 ) return 0;
|
||||
if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int32_t use_count_; // #shared
|
||||
int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
|
@@ -1,149 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_clang.hpp - __c11 clang intrinsics
|
||||
//
|
||||
// Copyright (c) 2007, 2013, 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
|
||||
|
||||
inline void atomic_increment( atomic_int_least32_t * pw )
|
||||
{
|
||||
__c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
|
||||
}
|
||||
|
||||
inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw )
|
||||
{
|
||||
return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
|
||||
}
|
||||
|
||||
inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
#endif
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
atomic_int_least32_t use_count_; // #shared
|
||||
atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base()
|
||||
{
|
||||
__c11_atomic_init( &use_count_, 1 );
|
||||
__c11_atomic_init( &weak_count_, 1 );
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE );
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
@@ -1,171 +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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( register long * pw )
|
||||
{
|
||||
register int a;
|
||||
|
||||
asm
|
||||
{
|
||||
loop:
|
||||
|
||||
lwarx a, 0, pw
|
||||
addi a, a, 1
|
||||
stwcx. a, 0, pw
|
||||
bne- loop
|
||||
}
|
||||
}
|
||||
|
||||
inline long atomic_decrement( register long * pw )
|
||||
{
|
||||
register int a;
|
||||
|
||||
asm
|
||||
{
|
||||
sync
|
||||
|
||||
loop:
|
||||
|
||||
lwarx a, 0, pw
|
||||
addi a, a, -1
|
||||
stwcx. a, 0, pw
|
||||
bne- loop
|
||||
|
||||
isync
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
inline long atomic_conditional_increment( register long * pw )
|
||||
{
|
||||
register int a;
|
||||
|
||||
asm
|
||||
{
|
||||
loop:
|
||||
|
||||
lwarx a, 0, pw
|
||||
cmpwi a, 0
|
||||
beq store
|
||||
|
||||
addi a, a, 1
|
||||
|
||||
store:
|
||||
|
||||
stwcx. a, 0, pw
|
||||
bne- loop
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<long const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
|
@@ -1,159 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2005 Rene Rivera
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
// int r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
asm
|
||||
{
|
||||
mov esi, [pw]
|
||||
mov eax, dv
|
||||
lock xadd dword ptr [esi], eax
|
||||
}
|
||||
}
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
//atomic_exchange_and_add( pw, 1 );
|
||||
|
||||
asm
|
||||
{
|
||||
mov esi, [pw]
|
||||
lock inc dword ptr [esi]
|
||||
}
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// int rv = *pw;
|
||||
// if( rv != 0 ) ++*pw;
|
||||
// return rv;
|
||||
|
||||
asm
|
||||
{
|
||||
mov esi, [pw]
|
||||
mov eax, dword ptr [esi]
|
||||
L0:
|
||||
test eax, eax
|
||||
je L1
|
||||
mov ebx, eax
|
||||
inc ebx
|
||||
lock cmpxchg dword ptr [esi], ebx
|
||||
jne L0
|
||||
L1:
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_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,158 +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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
int tmp;
|
||||
|
||||
// No barrier is required here but fetchadd always has an acquire or
|
||||
// release barrier associated with it. We choose release as it should be
|
||||
// cheaper.
|
||||
__asm__ ("fetchadd4.rel %0=%1,1" :
|
||||
"=r"(tmp), "=m"(*pw) :
|
||||
"m"( *pw ));
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int rv;
|
||||
|
||||
__asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
|
||||
" cmp.eq p7,p0=1,%0 ;; \n"
|
||||
"(p7) ld4.acq %0=%1 " :
|
||||
"=&r"(rv), "=m"(*pw) :
|
||||
"m"( *pw ) :
|
||||
"p7");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int rv, tmp, tmp2;
|
||||
|
||||
__asm__ ("0: ld4 %0=%3 ;; \n"
|
||||
" cmp.eq p7,p0=0,%0 ;; \n"
|
||||
"(p7) br.cond.spnt 1f \n"
|
||||
" mov ar.ccv=%0 \n"
|
||||
" add %1=1,%0 ;; \n"
|
||||
" cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
|
||||
" cmp.ne p7,p0=%0,%2 ;; \n"
|
||||
"(p7) br.cond.spnt 0b \n"
|
||||
" mov %0=%1 ;; \n"
|
||||
"1:" :
|
||||
"=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
|
||||
"m"( *pw ) :
|
||||
"ar.ccv", "p7");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
|
@@ -1,182 +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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
int tmp;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"0:\n\t"
|
||||
".set push\n\t"
|
||||
".set mips2\n\t"
|
||||
"ll %0, %1\n\t"
|
||||
"addiu %0, 1\n\t"
|
||||
"sc %0, %1\n\t"
|
||||
".set pop\n\t"
|
||||
"beqz %0, 0b":
|
||||
"=&r"( tmp ), "=m"( *pw ):
|
||||
"m"( *pw )
|
||||
);
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int rv, tmp;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"0:\n\t"
|
||||
".set push\n\t"
|
||||
".set mips2\n\t"
|
||||
"ll %1, %2\n\t"
|
||||
"addiu %0, %1, -1\n\t"
|
||||
"sc %0, %2\n\t"
|
||||
".set pop\n\t"
|
||||
"beqz %0, 0b\n\t"
|
||||
"addiu %0, %1, -1":
|
||||
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
|
||||
"m"( *pw ):
|
||||
"memory"
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int rv, tmp;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"0:\n\t"
|
||||
".set push\n\t"
|
||||
".set mips2\n\t"
|
||||
"ll %0, %2\n\t"
|
||||
"beqz %0, 1f\n\t"
|
||||
"addiu %1, %0, 1\n\t"
|
||||
"sc %1, %2\n\t"
|
||||
".set pop\n\t"
|
||||
"beqz %1, 0b\n\t"
|
||||
"addiu %0, %0, 1\n\t"
|
||||
"1:":
|
||||
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
|
||||
"m"( *pw ):
|
||||
"memory"
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
|
@@ -1,182 +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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
int tmp;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"0:\n\t"
|
||||
"lwarx %1, 0, %2\n\t"
|
||||
"addi %1, %1, 1\n\t"
|
||||
"stwcx. %1, 0, %2\n\t"
|
||||
"bne- 0b":
|
||||
|
||||
"=m"( *pw ), "=&b"( tmp ):
|
||||
"r"( pw ), "m"( *pw ):
|
||||
"cc"
|
||||
);
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int rv;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"sync\n\t"
|
||||
"0:\n\t"
|
||||
"lwarx %1, 0, %2\n\t"
|
||||
"addi %1, %1, -1\n\t"
|
||||
"stwcx. %1, 0, %2\n\t"
|
||||
"bne- 0b\n\t"
|
||||
"isync":
|
||||
|
||||
"=m"( *pw ), "=&b"( rv ):
|
||||
"r"( pw ), "m"( *pw ):
|
||||
"memory", "cc"
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int rv;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"0:\n\t"
|
||||
"lwarx %1, 0, %2\n\t"
|
||||
"cmpwi %1, 0\n\t"
|
||||
"beq 1f\n\t"
|
||||
"addi %1, %1, 1\n\t"
|
||||
"1:\n\t"
|
||||
"stwcx. %1, 0, %2\n\t"
|
||||
"bne- 0b":
|
||||
|
||||
"=m"( *pw ), "=&b"( rv ):
|
||||
"r"( pw ), "m"( *pw ):
|
||||
"cc"
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
|
@@ -1,167 +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 <inttypes.h> // int32_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
|
||||
{
|
||||
__asm__ __volatile__( "cas [%1], %2, %0"
|
||||
: "+r" (swap_)
|
||||
: "r" (dest_), "r" (compare_)
|
||||
: "memory" );
|
||||
|
||||
return swap_;
|
||||
}
|
||||
|
||||
inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
|
||||
{
|
||||
// long r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
int32_t r = *pw;
|
||||
|
||||
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void atomic_increment( int32_t * pw )
|
||||
{
|
||||
atomic_fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline int32_t atomic_decrement( int32_t * pw )
|
||||
{
|
||||
return atomic_fetch_and_add( pw, -1 );
|
||||
}
|
||||
|
||||
inline int32_t atomic_conditional_increment( int32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
int32_t r = *pw;
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int32_t use_count_; // #shared
|
||||
int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< int32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
@@ -1,174 +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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
// int r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
int r;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"lock\n\t"
|
||||
"xadd %1, %0":
|
||||
"=m"( *pw ), "=r"( r ): // outputs (%0, %1)
|
||||
"m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
|
||||
"memory", "cc" // clobbers
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
//atomic_exchange_and_add( pw, 1 );
|
||||
|
||||
__asm__
|
||||
(
|
||||
"lock\n\t"
|
||||
"incl %0":
|
||||
"=m"( *pw ): // output (%0)
|
||||
"m"( *pw ): // input (%1)
|
||||
"cc" // clobbers
|
||||
);
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// int rv = *pw;
|
||||
// if( rv != 0 ) ++*pw;
|
||||
// return rv;
|
||||
|
||||
int rv, tmp;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"movl %0, %%eax\n\t"
|
||||
"0:\n\t"
|
||||
"test %%eax, %%eax\n\t"
|
||||
"je 1f\n\t"
|
||||
"movl %%eax, %2\n\t"
|
||||
"incl %2\n\t"
|
||||
"lock\n\t"
|
||||
"cmpxchgl %2, %0\n\t"
|
||||
"jne 0b\n\t"
|
||||
"1:":
|
||||
"=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
|
||||
"m"( *pw ): // input (%3)
|
||||
"cc" // clobbers
|
||||
);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
|
@@ -1,108 +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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
++use_count_;
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
if( use_count_ == 0 ) return false;
|
||||
++use_count_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( --use_count_ == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
++weak_count_;
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( --weak_count_ == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return use_count_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
@@ -1,137 +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 <pthread.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
mutable pthread_mutex_t m_;
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
|
||||
|
||||
#if defined(__hpux) && defined(_DECTHREADS_)
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
|
||||
#else
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
++use_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
bool r = use_count_ == 0? false: ( ++use_count_, true );
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
return r;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long new_use_count = --use_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
if( new_use_count == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
++weak_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long new_weak_count = --weak_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
if( new_weak_count == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long r = use_count_;
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
@@ -1,162 +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 <inttypes.h> // uint32_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
|
||||
{
|
||||
return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
|
||||
}
|
||||
|
||||
inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
|
||||
{
|
||||
// long r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
uint32_t r = *pw;
|
||||
|
||||
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void atomic_increment( uint32_t * pw )
|
||||
{
|
||||
(void) __builtin_cellAtomicIncr32( pw );
|
||||
}
|
||||
|
||||
inline uint32_t atomic_decrement( uint32_t * pw )
|
||||
{
|
||||
return __builtin_cellAtomicDecr32( pw );
|
||||
}
|
||||
|
||||
inline uint32_t atomic_conditional_increment( uint32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
uint32_t r = *pw;
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
uint32_t use_count_; // #shared
|
||||
uint32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< uint32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
@@ -1,114 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_solaris.hpp
|
||||
// based on: detail/sp_counted_base_w32.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Michael van der Westhuizen
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <atomic.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
uint32_t use_count_; // #shared
|
||||
uint32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_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,132 +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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
|
||||
int r = *pw;
|
||||
*pw += dv;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
++*pw;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
|
||||
int rv = *pw;
|
||||
if( rv != 0 ) ++*pw;
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( &use_count_ );
|
||||
return use_count_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
@@ -1,137 +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 <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( std::atomic_int_least32_t * pw )
|
||||
{
|
||||
pw->fetch_add( 1, std::memory_order_relaxed );
|
||||
}
|
||||
|
||||
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw )
|
||||
{
|
||||
return pw->fetch_sub( 1, std::memory_order_acq_rel );
|
||||
}
|
||||
|
||||
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
std::int_least32_t r = pw->load( std::memory_order_relaxed );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
std::atomic_int_least32_t use_count_; // #shared
|
||||
std::atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return use_count_.load( std::memory_order_acquire );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
|
@@ -1,156 +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 <limits.h>
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if INT_MAX >= 2147483647
|
||||
|
||||
typedef int sp_int32_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef long sp_int32_t;
|
||||
|
||||
#endif
|
||||
|
||||
inline void atomic_increment( sp_int32_t * pw )
|
||||
{
|
||||
__sync_fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline sp_int32_t atomic_decrement( sp_int32_t * pw )
|
||||
{
|
||||
return __sync_fetch_and_add( pw, -1 );
|
||||
}
|
||||
|
||||
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
sp_int32_t r = *pw;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
|
||||
|
||||
if( r2 == r )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = r2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
sp_int32_t use_count_; // #shared
|
||||
sp_int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< sp_int32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
@@ -1,151 +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>
|
||||
|
||||
extern "builtin" void __lwsync(void);
|
||||
extern "builtin" void __isync(void);
|
||||
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
|
||||
extern "builtin" int __compare_and_swap(volatile int*, int*, int);
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int *pw )
|
||||
{
|
||||
// ++*pw;
|
||||
__lwsync();
|
||||
__fetch_and_add(pw, 1);
|
||||
__isync();
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int *pw )
|
||||
{
|
||||
// return --*pw;
|
||||
__lwsync();
|
||||
int originalValue = __fetch_and_add(pw, -1);
|
||||
__isync();
|
||||
|
||||
return (originalValue - 1);
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int *pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
__lwsync();
|
||||
int v = *const_cast<volatile int*>(pw);
|
||||
for (;;)
|
||||
// loop until state is known
|
||||
{
|
||||
if (v == 0) return 0;
|
||||
if (__compare_and_swap(pw, &v, v + 1))
|
||||
{
|
||||
__isync(); return (v + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
char pad[64] __attribute__((__aligned__(64)));
|
||||
// pad to prevent false sharing
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return *const_cast<volatile int*>(&use_count_);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
@@ -1,131 +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>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
long tmp = static_cast< long const volatile& >( use_count_ );
|
||||
if( tmp == 0 ) return false;
|
||||
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
|
||||
|
||||
// work around a code generation bug
|
||||
|
||||
long tmp2 = tmp + 1;
|
||||
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
|
||||
|
||||
#else
|
||||
|
||||
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( BOOST_SP_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<long const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
@@ -1,263 +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>
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
#include <boost/smart_ptr/detail/quick_allocator.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
#include <memory> // std::allocator
|
||||
#endif
|
||||
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
|
||||
void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
|
||||
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class X> class sp_counted_impl_p: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
X * px_;
|
||||
|
||||
sp_counted_impl_p( sp_counted_impl_p const & );
|
||||
sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
|
||||
|
||||
typedef sp_counted_impl_p<X> this_type;
|
||||
|
||||
public:
|
||||
|
||||
explicit sp_counted_impl_p( X * px ): px_( px )
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook( px, sizeof(X), this );
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
|
||||
#endif
|
||||
boost::checked_delete( px_ );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
{
|
||||
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
{
|
||||
return quick_allocator<this_type>::alloc();
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
quick_allocator<this_type>::dealloc( p );
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
// Borland's Codeguard trips up over the -Vx- option here:
|
||||
//
|
||||
#ifdef __CODEGUARD__
|
||||
# pragma option push -Vx-
|
||||
#endif
|
||||
|
||||
template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
P ptr; // copy constructor must not throw
|
||||
D del; // copy constructor must not throw
|
||||
|
||||
sp_counted_impl_pd( sp_counted_impl_pd const & );
|
||||
sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
|
||||
|
||||
typedef sp_counted_impl_pd<P, D> this_type;
|
||||
|
||||
public:
|
||||
|
||||
// pre: d(p) must not throw
|
||||
|
||||
sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
|
||||
{
|
||||
}
|
||||
|
||||
sp_counted_impl_pd( P p ): ptr( p ), del()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
{
|
||||
del( ptr );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return &reinterpret_cast<char&>( del );
|
||||
}
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
{
|
||||
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
{
|
||||
return quick_allocator<this_type>::alloc();
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
quick_allocator<this_type>::dealloc( p );
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
P p_; // copy constructor must not throw
|
||||
D d_; // copy constructor must not throw
|
||||
A a_; // copy constructor must not throw
|
||||
|
||||
sp_counted_impl_pda( sp_counted_impl_pda const & );
|
||||
sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
|
||||
|
||||
typedef sp_counted_impl_pda<P, D, A> this_type;
|
||||
|
||||
public:
|
||||
|
||||
// pre: d( p ) must not throw
|
||||
|
||||
sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
|
||||
{
|
||||
}
|
||||
|
||||
sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
{
|
||||
d_( p_ );
|
||||
}
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
|
||||
|
||||
#else
|
||||
|
||||
typedef typename A::template rebind< this_type >::other A2;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a_ );
|
||||
|
||||
this->~this_type();
|
||||
|
||||
a2.deallocate( this, 1 );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return &reinterpret_cast<char&>( d_ );
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __CODEGUARD__
|
||||
# pragma option pop
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
@@ -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
|
@@ -1,163 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/sp_interlocked.hpp
|
||||
//
|
||||
// Copyright 2005, 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// VC9 has intrin.h, but it collides with <utility>
|
||||
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600
|
||||
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets.
|
||||
#elif defined( __MINGW64_VERSION_MAJOR )
|
||||
|
||||
// MinGW-w64 provides intrin.h for both 32 and 64-bit targets.
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// Intel C++ on Windows on VC10+ stdlib
|
||||
#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
|
||||
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
|
||||
|
||||
#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H )
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#elif defined( _WIN32_WCE )
|
||||
|
||||
#if _WIN32_WCE >= 0x600
|
||||
|
||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#else
|
||||
|
||||
// under Windows CE we still have old-style Interlocked* functions
|
||||
|
||||
extern "C" long __cdecl InterlockedIncrement( long* );
|
||||
extern "C" long __cdecl InterlockedDecrement( long* );
|
||||
extern "C" long __cdecl InterlockedCompareExchange( long*, long, long );
|
||||
extern "C" long __cdecl InterlockedExchange( long*, long );
|
||||
extern "C" long __cdecl InterlockedExchangeAdd( long*, long );
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN )
|
||||
|
||||
#if defined( __CLRCALL_PURE_OR_CDECL )
|
||||
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
#else
|
||||
|
||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
# if defined( BOOST_MSVC ) && BOOST_MSVC == 1310
|
||||
//From MSDN, Visual Studio .NET 2003 spedific: To declare one of the interlocked functions
|
||||
//for use as an intrinsic, the function must be declared with the leading underscore and
|
||||
//the new function must appear in a #pragma intrinsic statement.
|
||||
# pragma intrinsic( _InterlockedIncrement )
|
||||
# pragma intrinsic( _InterlockedDecrement )
|
||||
# pragma intrinsic( _InterlockedCompareExchange )
|
||||
# pragma intrinsic( _InterlockedExchange )
|
||||
# pragma intrinsic( _InterlockedExchangeAdd )
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd
|
||||
|
||||
#else
|
||||
|
||||
# error "Interlocked intrinsics not available"
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
@@ -1,30 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_noexcept.hpp
|
||||
//
|
||||
// Copyright 2016 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_MSVC ) && BOOST_MSVC >= 1700 && BOOST_MSVC < 1900
|
||||
|
||||
#define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED
|
@@ -1,45 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_nullptr_t.hpp
|
||||
//
|
||||
// Copyright 2013 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
|
||||
|
||||
typedef decltype(nullptr) sp_nullptr_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef std::nullptr_t sp_nullptr_t;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
@@ -1,68 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/spinlock.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// struct spinlock
|
||||
// {
|
||||
// void lock();
|
||||
// bool try_lock();
|
||||
// void unlock();
|
||||
//
|
||||
// class scoped_lock;
|
||||
// };
|
||||
//
|
||||
// #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
|
||||
|
||||
#if defined( BOOST_SP_USE_STD_ATOMIC )
|
||||
# if !defined( __clang__ )
|
||||
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
|
||||
# else
|
||||
// Clang (at least up to 3.4) can't compile spinlock_pool when
|
||||
// using std::atomic, so substitute the __sync implementation instead.
|
||||
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
|
||||
# endif
|
||||
|
||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
|
||||
|
||||
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
|
||||
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
|
||||
|
||||
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
|
||||
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_HAS_SYNC )
|
||||
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
|
||||
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# include <boost/smart_ptr/detail/spinlock_w32.hpp>
|
||||
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
|
||||
|
||||
#elif !defined(BOOST_HAS_THREADS)
|
||||
# include <boost/smart_ptr/detail/spinlock_nt.hpp>
|
||||
|
||||
#else
|
||||
# error Unrecognized threading platform
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
@@ -1,121 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// Copyright (c) 2008, 2011 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER "dmb"
|
||||
# define BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
|
||||
# define BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER ""
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
int v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int r;
|
||||
|
||||
#ifdef BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
__asm__ __volatile__(
|
||||
"ldrex %0, [%2]; \n"
|
||||
"cmp %0, %1; \n"
|
||||
"strexne %0, %1, [%2]; \n"
|
||||
BOOST_SP_ARM_BARRIER :
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
#else
|
||||
|
||||
__asm__ __volatile__(
|
||||
"swp %0, %1, [%2];\n"
|
||||
BOOST_SP_ARM_BARRIER :
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
#endif
|
||||
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||
*const_cast< int volatile* >( &v_ ) = 0;
|
||||
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#undef BOOST_SP_ARM_BARRIER
|
||||
#undef BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
@@ -1,89 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
bool locked_;
|
||||
|
||||
public:
|
||||
|
||||
inline bool try_lock()
|
||||
{
|
||||
if( locked_ )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
locked_ = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void lock()
|
||||
{
|
||||
BOOST_ASSERT( !locked_ );
|
||||
locked_ = true;
|
||||
}
|
||||
|
||||
inline void unlock()
|
||||
{
|
||||
BOOST_ASSERT( locked_ );
|
||||
locked_ = false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { false }
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
@@ -1,91 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/spinlock_pool.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// spinlock_pool<0> is reserved for atomic<>, when/if it arrives
|
||||
// spinlock_pool<1> is reserved for shared_ptr reference counts
|
||||
// spinlock_pool<2> is reserved for shared_ptr atomic access
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/spinlock.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< int M > class spinlock_pool
|
||||
{
|
||||
private:
|
||||
|
||||
static spinlock pool_[ 41 ];
|
||||
|
||||
public:
|
||||
|
||||
static spinlock & spinlock_for( void const * pv )
|
||||
{
|
||||
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
|
||||
std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
|
||||
#else
|
||||
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
|
||||
#endif
|
||||
return pool_[ i ];
|
||||
}
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
|
||||
{
|
||||
sp_.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template< int M > spinlock spinlock_pool< M >::pool_[ 41 ] =
|
||||
{
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
@@ -1,79 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
pthread_mutex_t v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return pthread_mutex_trylock( &v_ ) == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
pthread_mutex_lock( &v_ );
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
pthread_mutex_unlock( &v_ );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
@@ -1,83 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
#include <atomic>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
std::atomic_flag v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return !v_.test_and_set( std::memory_order_acquire );
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
v_ .clear( std::memory_order_release );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT }
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
@@ -1,87 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
int v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int r = __sync_lock_test_and_set( &v_, 1 );
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
__sync_lock_release( &v_ );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
@@ -1,113 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
// BOOST_COMPILER_FENCE
|
||||
|
||||
#if defined(__INTEL_COMPILER)
|
||||
|
||||
#define BOOST_COMPILER_FENCE __memory_barrier();
|
||||
|
||||
#elif defined( _MSC_VER ) && _MSC_VER >= 1310
|
||||
|
||||
extern "C" void _ReadWriteBarrier();
|
||||
#pragma intrinsic( _ReadWriteBarrier )
|
||||
|
||||
#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_COMPILER_FENCE
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
long v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 );
|
||||
|
||||
BOOST_COMPILER_FENCE
|
||||
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
BOOST_COMPILER_FENCE
|
||||
*const_cast< long volatile* >( &v_ ) = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
@@ -1,177 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// yield_k.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
// Copyright (c) Microsoft Corporation 2014
|
||||
//
|
||||
// void yield( unsigned k );
|
||||
//
|
||||
// Typical use:
|
||||
//
|
||||
// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/predef.h>
|
||||
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
// BOOST_SMT_PAUSE
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
|
||||
|
||||
extern "C" void _mm_pause();
|
||||
|
||||
#define BOOST_SMT_PAUSE _mm_pause();
|
||||
|
||||
#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
|
||||
|
||||
#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
#if !BOOST_COMP_CLANG || !defined __MINGW32__
|
||||
extern "C" void __stdcall Sleep( unsigned long ms );
|
||||
#else
|
||||
#include <_mingw.h>
|
||||
#if !defined __MINGW64_VERSION_MAJOR
|
||||
extern "C" void __stdcall Sleep( unsigned long ms );
|
||||
#else
|
||||
extern "C" __declspec(dllimport) void __stdcall Sleep( unsigned long ms );
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline void yield( unsigned k )
|
||||
{
|
||||
if( k < 4 )
|
||||
{
|
||||
}
|
||||
#if defined( BOOST_SMT_PAUSE )
|
||||
else if( k < 16 )
|
||||
{
|
||||
BOOST_SMT_PAUSE
|
||||
}
|
||||
#endif
|
||||
#if !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
else if( k < 32 )
|
||||
{
|
||||
Sleep( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sleep( 1 );
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
// Sleep isn't supported on the Windows Runtime.
|
||||
std::this_thread::yield();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#elif defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
#ifndef _AIX
|
||||
#include <sched.h>
|
||||
#else
|
||||
// AIX's sched.h defines ::var which sometimes conflicts with Lambda's var
|
||||
extern "C" int sched_yield(void);
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void yield( unsigned k )
|
||||
{
|
||||
if( k < 4 )
|
||||
{
|
||||
}
|
||||
#if defined( BOOST_SMT_PAUSE )
|
||||
else if( k < 16 )
|
||||
{
|
||||
BOOST_SMT_PAUSE
|
||||
}
|
||||
#endif
|
||||
else if( k < 32 || k & 1 )
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
else
|
||||
{
|
||||
// g++ -Wextra warns on {} or {0}
|
||||
struct timespec rqtp = { 0, 0 };
|
||||
|
||||
// POSIX says that timespec has tv_sec and tv_nsec
|
||||
// But it doesn't guarantee order or placement
|
||||
|
||||
rqtp.tv_sec = 0;
|
||||
rqtp.tv_nsec = 1000;
|
||||
|
||||
nanosleep( &rqtp, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void yield( unsigned )
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
@@ -1,165 +0,0 @@
|
||||
#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
||||
#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// enable_shared_from_raw.hpp
|
||||
//
|
||||
// Copyright 2002, 2009, 2014 Peter Dimov
|
||||
// Copyright 2008-2009 Frank Mori Hess
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
|
||||
template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class enable_shared_from_raw
|
||||
{
|
||||
protected:
|
||||
|
||||
enable_shared_from_raw()
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_raw( enable_shared_from_raw const & )
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_raw & operator=( enable_shared_from_raw const & )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~enable_shared_from_raw()
|
||||
{
|
||||
BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init_if_expired() const
|
||||
{
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
||||
weak_this_ = shared_this_;
|
||||
}
|
||||
}
|
||||
|
||||
void init_if_empty() const
|
||||
{
|
||||
if( weak_this_._empty() )
|
||||
{
|
||||
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
||||
weak_this_ = shared_this_;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
template<class Y> friend class shared_ptr;
|
||||
template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
|
||||
template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
|
||||
template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||
#endif
|
||||
|
||||
shared_ptr<void const volatile> shared_from_this() const
|
||||
{
|
||||
init_if_expired();
|
||||
return shared_ptr<void const volatile>( weak_this_ );
|
||||
}
|
||||
|
||||
shared_ptr<void const volatile> shared_from_this() const volatile
|
||||
{
|
||||
return const_cast< enable_shared_from_raw const * >( this )->shared_from_this();
|
||||
}
|
||||
|
||||
weak_ptr<void const volatile> weak_from_this() const
|
||||
{
|
||||
init_if_empty();
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
weak_ptr<void const volatile> weak_from_this() const volatile
|
||||
{
|
||||
return const_cast< enable_shared_from_raw const * >( this )->weak_from_this();
|
||||
}
|
||||
|
||||
// Note: invoked automatically by shared_ptr; do not call
|
||||
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * ) const
|
||||
{
|
||||
BOOST_ASSERT( ppx != 0 );
|
||||
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
weak_this_ = *ppx;
|
||||
}
|
||||
else if( shared_this_.use_count() != 0 )
|
||||
{
|
||||
BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
|
||||
|
||||
detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
|
||||
BOOST_ASSERT( pd != 0 );
|
||||
|
||||
pd->set_deleter( *ppx );
|
||||
|
||||
ppx->reset( shared_this_, ppx->get() );
|
||||
shared_this_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
mutable weak_ptr<void const volatile> weak_this_;
|
||||
|
||||
private:
|
||||
|
||||
mutable shared_ptr<void const volatile> shared_this_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<T> shared_from_raw(T *p)
|
||||
{
|
||||
BOOST_ASSERT(p != 0);
|
||||
return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
boost::weak_ptr<T> weak_from_raw(T *p)
|
||||
{
|
||||
BOOST_ASSERT(p != 0);
|
||||
boost::weak_ptr<T> result;
|
||||
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_from_this(), p);
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe )
|
||||
{
|
||||
if( pe != 0 )
|
||||
{
|
||||
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
|
||||
}
|
||||
}
|
||||
} // namepsace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
@@ -1,90 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// enable_shared_from_this.hpp
|
||||
//
|
||||
// Copyright 2002, 2009 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/weak_ptr.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class enable_shared_from_this
|
||||
{
|
||||
protected:
|
||||
|
||||
enable_shared_from_this() BOOST_SP_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this(enable_shared_from_this const &) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~enable_shared_from_this() BOOST_SP_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
shared_ptr<T> shared_from_this()
|
||||
{
|
||||
shared_ptr<T> p( weak_this_ );
|
||||
BOOST_ASSERT( p.get() == this );
|
||||
return p;
|
||||
}
|
||||
|
||||
shared_ptr<T const> shared_from_this() const
|
||||
{
|
||||
shared_ptr<T const> p( weak_this_ );
|
||||
BOOST_ASSERT( p.get() == this );
|
||||
return p;
|
||||
}
|
||||
|
||||
weak_ptr<T> weak_from_this() BOOST_NOEXCEPT
|
||||
{
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
weak_ptr<T const> weak_from_this() const BOOST_NOEXCEPT
|
||||
{
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
public: // actually private, but avoids compiler template friendship issues
|
||||
|
||||
// Note: invoked automatically by shared_ptr; do not call
|
||||
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
|
||||
{
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
weak_this_ = shared_ptr<T>( *ppx, py );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mutable weak_ptr<T> weak_this_;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
@@ -1,361 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// intrusive_ptr.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
|
||||
|
||||
#include <boost/config/no_tr1/functional.hpp> // for std::less
|
||||
|
||||
#if !defined(BOOST_NO_IOSTREAM)
|
||||
#if !defined(BOOST_NO_IOSFWD)
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
#else
|
||||
#include <ostream>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//
|
||||
// intrusive_ptr
|
||||
//
|
||||
// A smart pointer that uses intrusive reference counting.
|
||||
//
|
||||
// Relies on unqualified calls to
|
||||
//
|
||||
// void intrusive_ptr_add_ref(T * p);
|
||||
// void intrusive_ptr_release(T * p);
|
||||
//
|
||||
// (p != 0)
|
||||
//
|
||||
// The object is responsible for destroying itself.
|
||||
//
|
||||
|
||||
template<class T> class intrusive_ptr
|
||||
{
|
||||
private:
|
||||
|
||||
typedef intrusive_ptr this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
BOOST_CONSTEXPR intrusive_ptr() BOOST_SP_NOEXCEPT : px( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
intrusive_ptr( T * p, bool add_ref = true ): px( p )
|
||||
{
|
||||
if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
template<class U>
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
|
||||
|
||||
#else
|
||||
|
||||
intrusive_ptr( intrusive_ptr<U> const & rhs )
|
||||
|
||||
#endif
|
||||
: px( rhs.get() )
|
||||
{
|
||||
if( px != 0 ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
|
||||
{
|
||||
if( px != 0 ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
|
||||
~intrusive_ptr()
|
||||
{
|
||||
if( px != 0 ) intrusive_ptr_release( px );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Move support
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
intrusive_ptr(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT : px( rhs.px )
|
||||
{
|
||||
rhs.px = 0;
|
||||
}
|
||||
|
||||
intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class U> friend class intrusive_ptr;
|
||||
|
||||
template<class U>
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
intrusive_ptr(intrusive_ptr<U> && rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty())
|
||||
|
||||
#else
|
||||
|
||||
intrusive_ptr(intrusive_ptr<U> && rhs)
|
||||
|
||||
#endif
|
||||
: px( rhs.px )
|
||||
{
|
||||
rhs.px = 0;
|
||||
}
|
||||
|
||||
template<class U>
|
||||
intrusive_ptr & operator=(intrusive_ptr<U> && rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< intrusive_ptr<U> && >( rhs ) ).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
intrusive_ptr & operator=(intrusive_ptr const & rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
intrusive_ptr & operator=(T * rhs)
|
||||
{
|
||||
this_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
this_type().swap( *this );
|
||||
}
|
||||
|
||||
void reset( T * rhs )
|
||||
{
|
||||
this_type( rhs ).swap( *this );
|
||||
}
|
||||
|
||||
void reset( T * rhs, bool add_ref )
|
||||
{
|
||||
this_type( rhs, add_ref ).swap( *this );
|
||||
}
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
T * detach() BOOST_NOEXCEPT
|
||||
{
|
||||
T * ret = px;
|
||||
px = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
T & operator*() const
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return *px;
|
||||
}
|
||||
|
||||
T * operator->() const
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return px;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
T * tmp = px;
|
||||
px = rhs.px;
|
||||
rhs.px = tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * px;
|
||||
};
|
||||
|
||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
|
||||
{
|
||||
return a.get() == b;
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
|
||||
{
|
||||
return a.get() != b;
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
|
||||
{
|
||||
return a != b.get();
|
||||
}
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
|
||||
|
||||
// Resolve the ambiguity between our op!= and the one in rel_ops
|
||||
|
||||
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return std::less<T *>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
// mem_fn support
|
||||
|
||||
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return static_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return const_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
|
||||
{
|
||||
return dynamic_cast<T *>(p.get());
|
||||
}
|
||||
|
||||
// operator<<
|
||||
|
||||
#if !defined(BOOST_NO_IOSTREAM)
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
|
||||
|
||||
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// in STLport's no-iostreams mode no iostream symbols can be used
|
||||
#ifndef _STLP_NO_IOSTREAMS
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
|
||||
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
|
||||
using std::basic_ostream;
|
||||
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
|
||||
# else
|
||||
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
|
||||
# endif
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif // _STLP_NO_IOSTREAMS
|
||||
|
||||
#endif // __GNUC__ < 3
|
||||
|
||||
#endif // !defined(BOOST_NO_IOSTREAM)
|
||||
|
||||
// hash_value
|
||||
|
||||
template< class T > struct hash;
|
||||
|
||||
template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
|
||||
{
|
||||
return boost::hash< T* >()( p.get() );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
|
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2013.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file intrusive_ref_counter.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.03.2009
|
||||
*
|
||||
* This header contains a reference counter class for \c intrusive_ptr.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
||||
#define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
// This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter:
|
||||
// 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
|
||||
// Note that there is no inline specifier in the declarations.
|
||||
#pragma warning(disable: 4396)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace sp_adl_block {
|
||||
|
||||
/*!
|
||||
* \brief Thread unsafe reference counter policy for \c intrusive_ref_counter
|
||||
*
|
||||
* The policy instructs the \c intrusive_ref_counter base class to implement
|
||||
* a reference counter suitable for single threaded use only. Pointers to the same
|
||||
* object with this kind of reference counter must not be used by different threads.
|
||||
*/
|
||||
struct thread_unsafe_counter
|
||||
{
|
||||
typedef unsigned int type;
|
||||
|
||||
static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return counter;
|
||||
}
|
||||
|
||||
static void increment(unsigned int& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
|
||||
static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return --counter;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Thread safe reference counter policy for \c intrusive_ref_counter
|
||||
*
|
||||
* The policy instructs the \c intrusive_ref_counter base class to implement
|
||||
* a thread-safe reference counter, if the target platform supports multithreading.
|
||||
*/
|
||||
struct thread_safe_counter
|
||||
{
|
||||
typedef boost::detail::atomic_count type;
|
||||
|
||||
static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< unsigned int >(static_cast< long >(counter));
|
||||
}
|
||||
|
||||
static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
|
||||
static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< unsigned int >(--counter);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
|
||||
class intrusive_ref_counter;
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
|
||||
/*!
|
||||
* \brief A reference counter base class
|
||||
*
|
||||
* This base class can be used with user-defined classes to add support
|
||||
* for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT.
|
||||
* Upon releasing the last \c intrusive_ptr referencing the object
|
||||
* derived from the \c intrusive_ref_counter class, operator \c delete
|
||||
* is automatically called on the pointer to the object.
|
||||
*
|
||||
* The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter.
|
||||
*/
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
class intrusive_ref_counter
|
||||
{
|
||||
private:
|
||||
//! Reference counter type
|
||||
typedef typename CounterPolicyT::type counter_type;
|
||||
//! Reference counter
|
||||
mutable counter_type m_ref_counter;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*
|
||||
* \post <tt>use_count() == 0</tt>
|
||||
*/
|
||||
intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*
|
||||
* \post <tt>use_count() == 0</tt>
|
||||
*/
|
||||
intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Assignment
|
||||
*
|
||||
* \post The reference counter is not modified after assignment
|
||||
*/
|
||||
intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }
|
||||
|
||||
/*!
|
||||
* \return The reference counter
|
||||
*/
|
||||
unsigned int use_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return CounterPolicyT::load(m_ref_counter);
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
|
||||
|
||||
friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
|
||||
{
|
||||
CounterPolicyT::increment(p->m_ref_counter);
|
||||
}
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
|
||||
{
|
||||
if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
|
||||
delete static_cast< const DerivedT* >(p);
|
||||
}
|
||||
|
||||
} // namespace sp_adl_block
|
||||
|
||||
using sp_adl_block::intrusive_ref_counter;
|
||||
using sp_adl_block::thread_unsafe_counter;
|
||||
using sp_adl_block::thread_safe_counter;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
@@ -1,22 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
||||
|
||||
// make_shared.hpp
|
||||
//
|
||||
// Copyright (c) 2007, 2008, 2012 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
||||
// for documentation.
|
||||
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE )
|
||||
# include <boost/smart_ptr/make_shared_array.hpp>
|
||||
# include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
Copyright 2012-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_MAKE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
inline typename detail::sp_if_size_array<T>::type
|
||||
make_shared()
|
||||
{
|
||||
return boost::allocate_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::sp_if_size_array<T>::type
|
||||
make_shared(const typename detail::sp_array_element<T>::type& value)
|
||||
{
|
||||
return boost::allocate_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size)
|
||||
{
|
||||
return boost::allocate_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size,
|
||||
const typename detail::sp_array_element<T>::type& value)
|
||||
{
|
||||
return boost::allocate_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size, value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::sp_if_size_array<T>::type
|
||||
make_shared_noinit()
|
||||
{
|
||||
return allocate_shared_noinit<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::sp_if_array<T>::type
|
||||
make_shared_noinit(std::size_t size)
|
||||
{
|
||||
return allocate_shared_noinit<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size);
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
@@ -1,801 +0,0 @@
|
||||
#ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
|
||||
|
||||
// make_shared_object.hpp
|
||||
//
|
||||
// Copyright (c) 2007, 2008, 2012 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
||||
// for documentation.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_forward.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< std::size_t N, std::size_t A > struct sp_aligned_storage
|
||||
{
|
||||
union type
|
||||
{
|
||||
char data_[ N ];
|
||||
typename boost::type_with_alignment< A >::type align_;
|
||||
};
|
||||
};
|
||||
|
||||
template< class T > class sp_ms_deleter
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
|
||||
|
||||
bool initialized_;
|
||||
storage_type storage_;
|
||||
|
||||
private:
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if( initialized_ )
|
||||
{
|
||||
#if defined( __GNUC__ )
|
||||
|
||||
// fixes incorrect aliasing warning
|
||||
T * p = reinterpret_cast< T* >( storage_.data_ );
|
||||
p->~T();
|
||||
|
||||
#else
|
||||
|
||||
reinterpret_cast< T* >( storage_.data_ )->~T();
|
||||
|
||||
#endif
|
||||
|
||||
initialized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
sp_ms_deleter() BOOST_NOEXCEPT : initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template<class A> explicit sp_ms_deleter( A const & ) BOOST_NOEXCEPT : initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
// optimization: do not copy storage_
|
||||
sp_ms_deleter( sp_ms_deleter const & ) BOOST_NOEXCEPT : initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
~sp_ms_deleter()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void operator()( T * )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
static void operator_fn( T* ) // operator() can't be static
|
||||
{
|
||||
}
|
||||
|
||||
void * address() BOOST_NOEXCEPT
|
||||
{
|
||||
return storage_.data_;
|
||||
}
|
||||
|
||||
void set_initialized() BOOST_NOEXCEPT
|
||||
{
|
||||
initialized_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
template< class T, class A > class sp_as_deleter
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
|
||||
|
||||
storage_type storage_;
|
||||
A a_;
|
||||
bool initialized_;
|
||||
|
||||
private:
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if( initialized_ )
|
||||
{
|
||||
T * p = reinterpret_cast< T* >( storage_.data_ );
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
std::allocator_traits<A>::destroy( a_, p );
|
||||
|
||||
#else
|
||||
|
||||
p->~T();
|
||||
|
||||
#endif
|
||||
|
||||
initialized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
sp_as_deleter( A const & a ) BOOST_NOEXCEPT : a_( a ), initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
// optimization: do not copy storage_
|
||||
sp_as_deleter( sp_as_deleter const & r ) BOOST_NOEXCEPT : a_( r.a_), initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
~sp_as_deleter()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void operator()( T * )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
static void operator_fn( T* ) // operator() can't be static
|
||||
{
|
||||
}
|
||||
|
||||
void * address() BOOST_NOEXCEPT
|
||||
{
|
||||
return storage_.data_;
|
||||
}
|
||||
|
||||
void set_initialized() BOOST_NOEXCEPT
|
||||
{
|
||||
initialized_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
template< class T > struct sp_if_not_array
|
||||
{
|
||||
typedef boost::shared_ptr< T > type;
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template< class T > struct sp_if_not_array< T[] >
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||
|
||||
template< class T, std::size_t N > struct sp_if_not_array< T[N] >
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||
# define BOOST_SP_MSD( T ) boost::detail::sp_inplace_tag< boost::detail::sp_ms_deleter< T > >()
|
||||
#else
|
||||
# define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >()
|
||||
#endif
|
||||
|
||||
// _noinit versions
|
||||
|
||||
template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared_noinit()
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T;
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared_noinit( A const & a )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T;
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
// Variadic templates, rvalue reference
|
||||
|
||||
template< class T, class... Args > typename boost::detail::sp_if_not_array< T >::type make_shared( Args && ... args )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class... Args > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, Args && ... args )
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
|
||||
A2 a2( a );
|
||||
|
||||
typedef boost::detail::sp_as_deleter< T, A2 > D;
|
||||
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a2 );
|
||||
|
||||
#else
|
||||
|
||||
typedef boost::detail::sp_ms_deleter< T > D;
|
||||
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a );
|
||||
|
||||
#endif
|
||||
|
||||
D * pd = static_cast< D* >( pt._internal_get_untyped_deleter() );
|
||||
void * pv = pd->address();
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
std::allocator_traits<A2>::construct( a2, static_cast< T* >( pv ), boost::detail::sp_forward<Args>( args )... );
|
||||
|
||||
#else
|
||||
|
||||
::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
|
||||
|
||||
#endif
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
#else // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
// Common zero-argument versions
|
||||
|
||||
template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared()
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T();
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T();
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
// C++03 version
|
||||
|
||||
template< class T, class A1 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 ),
|
||||
boost::forward<A6>( a6 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 ),
|
||||
boost::forward<A6>( a6 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 ),
|
||||
boost::forward<A6>( a6 ),
|
||||
boost::forward<A7>( a7 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 ),
|
||||
boost::forward<A6>( a6 ),
|
||||
boost::forward<A7>( a7 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 ),
|
||||
boost::forward<A6>( a6 ),
|
||||
boost::forward<A7>( a7 ),
|
||||
boost::forward<A8>( a8 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 ),
|
||||
boost::forward<A6>( a6 ),
|
||||
boost::forward<A7>( a7 ),
|
||||
boost::forward<A8>( a8 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8, BOOST_FWD_REF(A9) a9 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 ),
|
||||
boost::forward<A6>( a6 ),
|
||||
boost::forward<A7>( a7 ),
|
||||
boost::forward<A8>( a8 ),
|
||||
boost::forward<A9>( a9 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||
typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8, BOOST_FWD_REF(A9) a9 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::forward<A1>( a1 ),
|
||||
boost::forward<A2>( a2 ),
|
||||
boost::forward<A3>( a3 ),
|
||||
boost::forward<A4>( a4 ),
|
||||
boost::forward<A5>( a5 ),
|
||||
boost::forward<A6>( a6 ),
|
||||
boost::forward<A7>( a7 ),
|
||||
boost::forward<A8>( a8 ),
|
||||
boost::forward<A9>( a9 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
#endif // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
#undef BOOST_SP_MSD
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
|
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
Copyright 2012-2015 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_MAKE_UNIQUE_HPP
|
||||
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
struct up_if_object {
|
||||
typedef std::unique_ptr<T> type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_if_object<T[]> { };
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct up_if_object<T[N]> { };
|
||||
|
||||
template<class T>
|
||||
struct up_if_array { };
|
||||
|
||||
template<class T>
|
||||
struct up_if_array<T[]> {
|
||||
typedef std::unique_ptr<T[]> type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_remove_reference {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_remove_reference<T&> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_remove_reference<T&&> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_element { };
|
||||
|
||||
template<class T>
|
||||
struct up_element<T[]> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_object<T>::type
|
||||
make_unique()
|
||||
{
|
||||
return std::unique_ptr<T>(new T());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class T, class... Args>
|
||||
inline typename detail::up_if_object<T>::type
|
||||
make_unique(Args&&... args)
|
||||
{
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_object<T>::type
|
||||
make_unique(typename detail::up_remove_reference<T>::type&& value)
|
||||
{
|
||||
return std::unique_ptr<T>(new T(std::move(value)));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_object<T>::type
|
||||
make_unique_noinit()
|
||||
{
|
||||
return std::unique_ptr<T>(new T);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_array<T>::type
|
||||
make_unique(std::size_t size)
|
||||
{
|
||||
return std::unique_ptr<T>(new typename
|
||||
detail::up_element<T>::type[size]());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename detail::up_if_array<T>::type
|
||||
make_unique_noinit(std::size_t size)
|
||||
{
|
||||
return std::unique_ptr<T>(new typename
|
||||
detail::up_element<T>::type[size]);
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user