Compare commits

..

3 Commits

Author SHA1 Message Date
nobody
9a3b8034eb This commit was manufactured by cvs2svn to create tag
'Version_1_33_0'.

[SVN r30532]
2005-08-12 03:25:34 +00:00
Jonathan Turkanis
72c5cc395a fixed broken links
[SVN r30431]
2005-08-03 21:42:39 +00:00
nobody
9945f4e158 This commit was manufactured by cvs2svn to create branch 'RC_1_33_0'.
[SVN r30300]
2005-07-28 18:22:24 +00:00
237 changed files with 3108 additions and 20298 deletions

View File

@@ -1,88 +1,105 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Smart Pointer Changes</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>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">&lt;boost/smart_ptr.hpp&gt;</a>
header now includes the headers for the four classic smart pointer class
templates.
<li>
The <b>weak_ptr</b>
template was added.
<li>
The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that
the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
destructor. This makes it easier to have shared_ptr members in classes without
explicit destructors.
<li>
A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
<li>
<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
and <b>dynamic_cast</b>
do for pointers.
<li>
The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
results in undefined behavior (an assertion, or eventually a double-delete if
assertions are off).
<li>
The <b>BOOST_SMART_PTR_CONVERSION</b>
feature has been removed.
<li>
<b>shared_ptr&lt;void&gt;</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">
&lt;boost/detail/atomic_count.hpp&gt;</a>
file for details
<li>
The new shared_ptr will always delete the object using the pointer it was
originally constructed with. This prevents subtle problems that could happen if
the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did
not have a virtual destructor.</li>
</ul>
<h2>Implementation Details</h2>
<ul>
<li>
Some bugs in the assignment operator implementations and in <b>reset</b>
have been fixed by using the "copy and swap" idiom.
<li>
Assertions have been added to check preconditions of various functions;
however, since these use the new <a href="../../boost/assert.hpp">&lt;boost/assert.hpp&gt;</a>
header, the assertions are disabled by default.
<li>
The partial specialization of <b>std::less</b> has been replaced by <b>operator&lt;</b>
overloads which accomplish the same thing without relying on undefined
behavior.
<li>
The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>,
which has many of the same advantages for generic programming but does not
violate the C++ standard.</li>
</ul>
<hr>
<p>Revised 1 February 2002</p>
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Smart Pointer Changes</title>
</head>
<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">&lt;boost/smart_ptr.hpp&gt;</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>
<li>The <b>BOOST_SMART_PTR_CONVERSION</b> feature has been removed.</li>
<li><b>shared_ptr&lt;void&gt;</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">&lt;boost/detail/atomic_count.hpp&gt;</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 &quot;copy and swap&quot; idiom.</li>
<li>Assertions have been added to check preconditions of various functions;
however, since these use the new
<a href="../../boost/assert.hpp">&lt;boost/assert.hpp&gt;</a>
header, the assertions are disabled by default.</li>
<li>The partial specialization of <b>std::less</b> has been replaced by <b>operator&lt;</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>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 &quot;as is&quot;
without express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
</body>
</html>

View File

@@ -7,9 +7,10 @@
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
<table border="0" width="100%">
<tr>
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
<td width="277">
<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
</td>
<td align="center">
<td align="middle">
<h1>enable_shared_from_this.hpp</h1>
</td>
</tr>
@@ -29,24 +30,20 @@
and <STRONG>shared_ptr&lt;T const&gt;</STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
<h3><a name="Example">Example</a></h3>
<pre>
#include &lt;boost/enable_shared_from_this.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
#include &lt;cassert&gt;
class Y: public boost::enable_shared_from_this&lt;Y&gt;
class Y: public enable_shared_from_this&lt;Y&gt;
{
public:
boost::shared_ptr&lt;Y&gt; f()
shared_ptr&lt;Y&gt; f()
{
return shared_from_this();
}
};
}
int main()
{
boost::shared_ptr&lt;Y&gt; p(new Y);
boost::shared_ptr&lt;Y&gt; q = p-&gt;f();
shared_ptr&lt;Y&gt; p(new Y);
shared_ptr&lt;Y&gt; q = p-&gt;f();
assert(p == q);
assert(!(p &lt; q || q &lt; p)); // p and q must share ownership
}
@@ -88,8 +85,9 @@ public:
</blockquote>
<p>
<br>
<small>Copyright <20> 2002, 2003 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>
<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>

View File

@@ -12,10 +12,97 @@
//
// 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>
#include <boost/config.hpp>
#ifndef BOOST_HAS_THREADS
namespace boost
{
namespace detail
{
typedef long atomic_count;
}
}
#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__) || defined(__GLIBCXX__)
# 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

View File

@@ -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
@@ -17,11 +17,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
# include <ext/atomicity.h>
#else
# include <bits/atomicity.h>
#endif
#include <bits/atomicity.h>
namespace boost
{
@@ -40,21 +36,21 @@ class atomic_count
{
public:
explicit atomic_count( long v ) : value_( v ) {}
explicit atomic_count(long v) : value_(v) {}
long operator++()
void operator++()
{
return __exchange_and_add( &value_, +1 ) + 1;
__atomic_add(&value_, 1);
}
long operator--()
{
return __exchange_and_add( &value_, -1 ) - 1;
return __exchange_and_add(&value_, -1) - 1;
}
operator long() const
{
return __exchange_and_add( &value_, 0 );
return __exchange_and_add(&value_, 0);
}
private:
@@ -69,4 +65,4 @@ private:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED

View File

@@ -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
@@ -62,10 +62,10 @@ public:
pthread_mutex_destroy(&mutex_);
}
long operator++()
void operator++()
{
scoped_lock lock(mutex_);
return ++value_;
++value_;
}
long operator--()
@@ -93,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

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -60,4 +60,4 @@ private:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
#ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED
#define BOOST_BAD_WEAK_PTR_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -8,7 +8,7 @@
#endif
//
// boost/smart_ptr/bad_weak_ptr.hpp
// detail/bad_weak_ptr.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
//
@@ -42,7 +42,7 @@ public:
virtual char const * what() const throw()
{
return "tr1::bad_weak_ptr";
return "boost::bad_weak_ptr";
}
};
@@ -56,4 +56,4 @@ public:
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
#endif
#endif // #ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
#endif // #ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED

View File

@@ -12,11 +12,31 @@
//
// 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 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/smart_ptr/detail/lightweight_mutex.hpp>
#include <boost/config.hpp>
#if !defined(BOOST_HAS_THREADS)
# include <boost/detail/lwm_nop.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/lwm_win32_cs.hpp>
#elif defined(BOOST_HAS_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

View File

@@ -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

View File

@@ -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

View File

@@ -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
@@ -29,7 +29,7 @@ namespace detail
#ifndef BOOST_USE_WINDOWS_H
struct critical_section
struct CRITICAL_SECTION
{
struct critical_section_debug * DebugInfo;
long LockCount;
@@ -43,14 +43,10 @@ struct critical_section
#endif
};
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 *);
#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
@@ -58,7 +54,7 @@ class lightweight_mutex
{
private:
critical_section cs_;
CRITICAL_SECTION cs_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
@@ -105,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

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
#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
@@ -17,7 +17,7 @@
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#include <boost/detail/atomic_count.hpp>
#include <cstddef> // for std::ptrdiff_t
#include <algorithm> // for std::swap
@@ -148,4 +148,4 @@ template<class T> void swap(shared_array<T> & a, shared_array<T> & b)
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED

View File

@@ -0,0 +1,330 @@
#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.
// 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/detail/bad_weak_ptr.hpp>
#include <boost/detail/sp_counted_base.hpp>
#include <boost/detail/sp_counted_impl.hpp>
#include <memory> // std::auto_ptr, std::allocator
#include <functional> // std::less
#include <new> // std::bad_alloc
#include <typeinfo> // std::type_info in get_deleter
namespace boost
{
namespace detail
{
#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 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
}
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_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
}
#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
~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;
}
};
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() )
{
boost::throw_exception( boost::bad_weak_ptr() );
}
}
} // namespace detail
} // namespace boost
#ifdef __BORLANDC__
# pragma warn .8027 // Functions containing try are not expanded inline
#endif
#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
#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
@@ -17,7 +17,7 @@
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#include <boost/detail/atomic_count.hpp>
#ifndef BOOST_NO_AUTO_PTR
# include <memory> // for std::auto_ptr
@@ -179,4 +179,4 @@ template<class T> inline T * get_pointer(shared_ptr<T> const & p)
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED

View File

@@ -0,0 +1,69 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
#define BOOST_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 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_DISABLE_THREADS )
# include <boost/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_USE_PTHREADS )
# include <boost/detail/sp_counted_base_pt.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
# include <boost/detail/sp_counted_base_gcc_x86.hpp>
//~ #elif defined( __MWERKS__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
//~ # include <boost/detail/sp_counted_base_cw_x86.hpp>
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
# include <boost/detail/sp_counted_base_gcc_ia64.hpp>
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
# include <boost/detail/sp_counted_base_cw_ppc.hpp>
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) )
# include <boost/detail/sp_counted_base_gcc_ppc.hpp>
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
# include <boost/detail/sp_counted_base_w32.hpp>
#elif !defined( BOOST_HAS_THREADS )
# include <boost/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_HAS_PTHREADS )
# include <boost/detail/sp_counted_base_pt.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error
# error Unrecognized threading platform
#endif
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -24,7 +24,7 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <typeinfo>
namespace boost
{
@@ -34,61 +34,55 @@ 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
lwarx r4, 0, r3
addi r4, r4, 1
stwcx. r4, 0, r3
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
lwarx r4, 0, r3
addi r4, r4, -1
stwcx. r4, 0, r3
bne- loop
mr r3, r4
isync
}
return a;
}
inline long atomic_conditional_increment( register long * pw )
{
register int a;
asm
{
loop:
lwarx a, 0, pw
cmpwi a, 0
lwarx r4, 0, r3
cmpwi r4, 0
beq store
addi a, a, 1
addi r4, r4, 1
store:
stwcx. a, 0, pw
stwcx. r4, 0, r3
bne- loop
}
return a;
mr r3, r4
}
}
class sp_counted_base
@@ -123,8 +117,7 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
@@ -168,4 +161,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -25,7 +25,7 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <typeinfo>
namespace boost
{
@@ -111,8 +111,7 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
@@ -156,4 +155,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED

View File

@@ -1,11 +1,11 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
#define BOOST_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 2004-2005 Peter Dimov
// Copyright 2005 Ben Hutchings
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -16,7 +16,7 @@
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <typeinfo>
namespace boost
{
@@ -24,55 +24,55 @@ namespace boost
namespace detail
{
inline void atomic_increment( int * pw )
inline void atomic_increment( long * pw )
{
// ++*pw;
int tmp;
long 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" :
__asm__ ("fetchadd8.rel %0=[%2],1" :
"=r"(tmp), "=m"(*pw) :
"m"( *pw ));
"r"(pw));
}
inline int atomic_decrement( int * pw )
inline long atomic_decrement( long * pw )
{
// return --*pw;
int rv;
long rv;
__asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
__asm__ (" fetchadd8.rel %0=[%2],-1 ;; \n"
" cmp.eq p7,p0=1,%0 ;; \n"
"(p7) ld4.acq %0=%1 " :
"(p7) ld8.acq %0=[%2] " :
"=&r"(rv), "=m"(*pw) :
"m"( *pw ) :
"r"(pw) :
"p7");
return rv;
}
inline int atomic_conditional_increment( int * pw )
inline long atomic_conditional_increment( long * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv, tmp, tmp2;
long rv, tmp, tmp2;
__asm__ ("0: ld4 %0=%3 ;; \n"
__asm__ ("0: ld8 %0=[%4] ;; \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"
" cmpxchg8.acq %2=[%4],%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 ) :
"r"(pw) :
"ar.ccv", "p7");
return rv;
@@ -85,8 +85,8 @@ 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)
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
@@ -110,8 +110,7 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
@@ -147,7 +146,7 @@ public:
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
return static_cast<long const volatile &>( use_count_ );
}
};
@@ -155,4 +154,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -24,7 +24,7 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <typeinfo>
namespace boost
{
@@ -32,11 +32,11 @@ namespace boost
namespace detail
{
inline void atomic_increment( int * pw )
inline void atomic_increment( long * pw )
{
// ++*pw;
int tmp;
long tmp;
__asm__
(
@@ -47,16 +47,16 @@ inline void atomic_increment( int * pw )
"bne- 0b":
"=m"( *pw ), "=&b"( tmp ):
"r"( pw ), "m"( *pw ):
"r"( pw ):
"cc"
);
}
inline int atomic_decrement( int * pw )
inline long atomic_decrement( long * pw )
{
// return --*pw;
int rv;
long rv;
__asm__ __volatile__
(
@@ -69,19 +69,19 @@ inline int atomic_decrement( int * pw )
"isync":
"=m"( *pw ), "=&b"( rv ):
"r"( pw ), "m"( *pw ):
"r"( pw ):
"memory", "cc"
);
return rv;
}
inline int atomic_conditional_increment( int * pw )
inline long atomic_conditional_increment( long * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv;
long rv;
__asm__
(
@@ -95,7 +95,7 @@ inline int atomic_conditional_increment( int * pw )
"bne- 0b":
"=m"( *pw ), "=&b"( rv ):
"r"( pw ), "m"( *pw ):
"r"( pw ):
"cc"
);
@@ -109,8 +109,8 @@ 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)
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
@@ -134,8 +134,7 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
@@ -171,7 +170,7 @@ public:
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
return static_cast<long const volatile &>( use_count_ );
}
};
@@ -179,4 +178,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -24,7 +24,7 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <typeinfo>
namespace boost
{
@@ -126,8 +126,7 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
@@ -171,4 +170,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -18,7 +18,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/sp_typeinfo.hpp>
#include <typeinfo>
namespace boost
{
@@ -58,8 +58,7 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
@@ -105,4 +104,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -18,7 +18,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/sp_typeinfo.hpp>
#include <typeinfo>
#include <pthread.h>
namespace boost
@@ -69,8 +69,7 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
@@ -133,4 +132,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -25,8 +25,7 @@
//
#include <boost/detail/interlocked.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/detail/sp_typeinfo.hpp>
#include <typeinfo>
namespace boost
{
@@ -66,8 +65,7 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
@@ -80,19 +78,7 @@ public:
{
long tmp = static_cast< long const volatile& >( use_count_ );
if( tmp == 0 ) return false;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
// work around a code generation bug
long tmp2 = tmp + 1;
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
#else
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
#endif
}
}
@@ -128,4 +114,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
#ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -25,16 +25,14 @@
#endif
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/detail/sp_counted_base.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#include <boost/smart_ptr/detail/quick_allocator.hpp>
#include <boost/detail/quick_allocator.hpp>
#endif
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
#include <memory> // std::allocator
#endif
#include <typeinfo> // std::type_info in get_deleter
#include <cstddef> // std::size_t
namespace boost
@@ -78,12 +76,7 @@ public:
boost::checked_delete( px_ );
}
virtual void * get_deleter( detail::sp_typeinfo const & )
{
return 0;
}
virtual void * get_untyped_deleter()
virtual void * get_deleter( std::type_info const & )
{
return 0;
}
@@ -140,11 +133,7 @@ public:
// pre: d(p) must not throw
sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
{
}
sp_counted_impl_pd( P p ): ptr( p ), del()
sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
{
}
@@ -153,14 +142,9 @@ public:
del( ptr );
}
virtual void * get_deleter( detail::sp_typeinfo const & ti )
virtual void * get_deleter( std::type_info const & ti )
{
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
}
virtual void * get_untyped_deleter()
{
return &reinterpret_cast<char&>( del );
return ti == typeid(D)? &del: 0;
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
@@ -192,57 +176,6 @@ public:
#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 )
{
}
virtual void dispose() // nothrow
{
d_( p_ );
}
virtual void destroy() // nothrow
{
typedef typename A::template rebind< this_type >::other A2;
A2 a2( a_ );
this->~this_type();
a2.deallocate( this, 1 );
}
virtual void * get_deleter( detail::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
@@ -251,4 +184,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED

View File

@@ -1,135 +0,0 @@
#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_typeinfo.hpp
//
// 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)
#include <boost/config.hpp>
#if defined( BOOST_NO_TYPEID )
#include <boost/current_function.hpp>
#include <functional>
namespace boost
{
namespace detail
{
class sp_typeinfo
{
private:
sp_typeinfo( sp_typeinfo const& );
sp_typeinfo& operator=( sp_typeinfo const& );
char const * name_;
public:
explicit sp_typeinfo( char const * name ): name_( name )
{
}
bool operator==( sp_typeinfo const& rhs ) const
{
return this == &rhs;
}
bool operator!=( sp_typeinfo const& rhs ) const
{
return this != &rhs;
}
bool before( sp_typeinfo const& rhs ) const
{
return std::less< sp_typeinfo const* >()( this, &rhs );
}
char const* name() const
{
return name_;
}
};
template<class T> struct sp_typeid_
{
static sp_typeinfo ti_;
static char const * name()
{
return BOOST_CURRENT_FUNCTION;
}
};
#if defined(__SUNPRO_CC)
// see #4199, the Sun Studio compiler gets confused about static initialization
// constructor arguments. But an assignment works just fine.
template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
#else
template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
#endif
template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
{
};
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_<T>::ti_)
#else
#include <typeinfo>
namespace boost
{
namespace detail
{
#if defined( BOOST_NO_STD_TYPEINFO )
typedef ::type_info sp_typeinfo;
#else
typedef std::type_info sp_typeinfo;
#endif
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID(T) typeid(T)
#endif
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED

View File

@@ -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

View File

@@ -3,15 +3,9 @@
// 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
# define GET_POINTER_DWA20021219_HPP
#include <boost/config.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 <memory>
namespace boost {
@@ -29,19 +23,6 @@ template<class T> T * get_pointer(std::auto_ptr<T> const& p)
return p.get();
}
#if !defined( BOOST_NO_CXX11_SMART_PTR )
template<class T> T * get_pointer( std::unique_ptr<T> const& p )
{
return p.get();
}
template<class T> T * get_pointer( std::shared_ptr<T> const& p )
{
return p.get();
}
#endif
} // namespace boost

View File

@@ -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

View File

@@ -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

View File

@@ -1,53 +0,0 @@
#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
#define BOOST_MEMORY_ORDER_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/memory_order.hpp
//
// Defines enum boost::memory_order per the C++0x working draft
//
// 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)
namespace boost
{
//
// Enum values are chosen so that code that needs to insert
// a trailing fence for acquire semantics can use a single
// test such as:
//
// if( mo & memory_order_acquire ) { ...fence... }
//
// For leading fences one can use:
//
// if( mo & memory_order_release ) { ...fence... }
//
// Architectures such as Alpha that need a fence on consume
// can use:
//
// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... }
//
enum memory_order
{
memory_order_relaxed = 0,
memory_order_acquire = 1,
memory_order_release = 2,
memory_order_acq_rel = 3, // acquire | release
memory_order_seq_cst = 7, // acq_rel | 4
memory_order_consume = 8
};
} // namespace boost
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED

View File

@@ -1,45 +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
namespace boost {
//static_pointer_cast overload for raw pointers
template<class T, class U>
inline T* static_pointer_cast(U *ptr)
{
return static_cast<T*>(ptr);
}
//dynamic_pointer_cast overload for raw pointers
template<class T, class U>
inline T* dynamic_pointer_cast(U *ptr)
{
return dynamic_cast<T*>(ptr);
}
//const_pointer_cast overload for raw pointers
template<class T, class U>
inline T* const_pointer_cast(U *ptr)
{
return const_cast<T*>(ptr);
}
//reinterpret_pointer_cast overload for raw pointers
template<class T, class U>
inline T* reinterpret_pointer_cast(U *ptr)
{
return reinterpret_cast<T*>(ptr);
}
} // namespace boost
#endif //BOOST_POINTER_CAST_HPP

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,465 @@
// 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 ) // 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__, < 0x3200) ) || \
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) )
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__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
// apparently EDG 2.38 and HP aCC A.03.35 also don'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

View File

@@ -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

View File

@@ -1,250 +0,0 @@
/*
* Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/allocate_array_helper.hpp>
#include <boost/smart_ptr/detail/array_deleter.hpp>
#include <boost/smart_ptr/detail/array_traits.hpp>
#include <boost/smart_ptr/detail/sp_if_array.hpp>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
namespace boost {
template<typename T, typename A>
inline typename boost::detail::sp_if_array<T>::type
allocate_shared(const A& allocator, std::size_t size) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
T1* p1 = 0;
T2* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2);
return boost::shared_ptr<T>(s1, p1);
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename T, typename A, typename... Args>
inline typename boost::detail::sp_if_array<T>::type
allocate_shared(const A& allocator, std::size_t size, Args&&... args) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
T1* p1 = 0;
T2* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
return boost::shared_ptr<T>(s1, p1);
}
template<typename T, typename A, typename... Args>
inline typename boost::detail::sp_if_size_array<T>::type
allocate_shared(const A& allocator, Args&&... args) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
enum {
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
return boost::shared_ptr<T>(s1, p1);
}
#endif
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
template<typename T, typename A>
inline typename boost::detail::sp_if_size_array<T>::type
allocate_shared(const A& allocator, const T& list) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3;
enum {
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
T3* p3 = 0;
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p3 = reinterpret_cast<T3*>(list);
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init_list(p2, p3);
return boost::shared_ptr<T>(s1, p1);
}
template<typename T, typename A>
inline typename boost::detail::sp_if_array<T>::type
allocate_shared(const A& allocator, std::size_t size,
const typename boost::detail::array_inner<T>::type& list) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3;
enum {
M = boost::detail::array_total<T1>::size
};
T1* p1 = 0;
T2* p2 = 0;
T3* p3 = 0;
std::size_t n1 = M * size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p3 = reinterpret_cast<T3*>(list);
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->template init_list<M>(p2, p3);
return boost::shared_ptr<T>(s1, p1);
}
template<typename T, typename A>
inline typename boost::detail::sp_if_size_array<T>::type
allocate_shared(const A& allocator,
const typename boost::detail::array_inner<T>::type& list) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3;
enum {
M = boost::detail::array_total<T1>::size,
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
T3* p3 = 0;
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p3 = reinterpret_cast<T3*>(list);
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->template init_list<M>(p2, p3);
return boost::shared_ptr<T>(s1, p1);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template<typename T, typename A>
inline typename boost::detail::sp_if_array<T>::type
allocate_shared(const A& allocator,
std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3;
T1* p1 = 0;
T2* p2 = 0;
T3* p3 = 0;
std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p3 = reinterpret_cast<T3*>(list.begin());
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init_list(p2, p3);
return boost::shared_ptr<T>(s1, p1);
}
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename T, typename A>
inline typename boost::detail::sp_if_array<T>::type
allocate_shared(const A& allocator, std::size_t size,
typename boost::detail::array_base<T>::type&& value) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
T1* p1 = 0;
T2* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2, boost::detail::sp_forward<T2>(value));
return boost::shared_ptr<T>(s1, p1);
}
template<typename T, typename A>
inline typename boost::detail::sp_if_size_array<T>::type
allocate_shared(const A& allocator,
typename boost::detail::array_base<T>::type&& value) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
enum {
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2, boost::detail::sp_forward<T2>(value));
return boost::shared_ptr<T>(s1, p1);
}
#endif
#endif
template<typename T, typename A>
inline typename boost::detail::sp_if_array<T>::type
allocate_shared_noinit(const A& allocator, std::size_t size) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
T1* p1 = 0;
T2* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->noinit(p2);
return boost::shared_ptr<T>(s1, p1);
}
template<typename T, typename A>
inline typename boost::detail::sp_if_size_array<T>::type
allocate_shared_noinit(const A& allocator) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
enum {
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->noinit(p2);
return boost::shared_ptr<T>(s1, p1);
}
}
#endif

View File

@@ -1,169 +0,0 @@
/*
* Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
#define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
#include <boost/type_traits/alignment_of.hpp>
namespace boost {
namespace detail {
template<typename A, typename T, typename Y = char>
class allocate_array_helper;
template<typename A, typename T, typename Y>
class allocate_array_helper<A, T[], Y> {
template<typename A9, typename T9, typename Y9>
friend class allocate_array_helper;
typedef typename A::template rebind<Y> ::other A2;
typedef typename A::template rebind<char>::other A3;
public:
typedef typename A2::value_type value_type;
typedef typename A2::pointer pointer;
typedef typename A2::const_pointer const_pointer;
typedef typename A2::reference reference;
typedef typename A2::const_reference const_reference;
typedef typename A2::size_type size_type;
typedef typename A2::difference_type difference_type;
template<typename U>
struct rebind {
typedef allocate_array_helper<A, T[], U> other;
};
allocate_array_helper(const A& allocator_, std::size_t size_, T** data_)
: allocator(allocator_),
size(sizeof(T) * size_),
data(data_) {
}
template<class U>
allocate_array_helper(const allocate_array_helper<A, T[], U>& other)
: allocator(other.allocator),
size(other.size),
data(other.data) {
}
pointer address(reference value) const {
return allocator.address(value);
}
const_pointer address(const_reference value) const {
return allocator.address(value);
}
size_type max_size() const {
return allocator.max_size();
}
pointer allocate(size_type count, const void* value = 0) {
std::size_t a1 = boost::alignment_of<T>::value;
std::size_t n1 = count * sizeof(Y) + a1 - 1;
char* p1 = A3(allocator).allocate(n1 + size, value);
char* p2 = p1 + n1;
while (std::size_t(p2) % a1 != 0) {
p2--;
}
*data = reinterpret_cast<T*>(p2);
return reinterpret_cast<Y*>(p1);
}
void deallocate(pointer memory, size_type count) {
std::size_t a1 = boost::alignment_of<T>::value;
std::size_t n1 = count * sizeof(Y) + a1 - 1;
char* p1 = reinterpret_cast<char*>(memory);
A3(allocator).deallocate(p1, n1 + size);
}
void construct(pointer memory, const Y& value) {
allocator.construct(memory, value);
}
void destroy(pointer memory) {
allocator.destroy(memory);
}
template<typename U>
bool operator==(const allocate_array_helper<A, T[], U>& other) const {
return allocator == other.allocator;
}
template<typename U>
bool operator!=(const allocate_array_helper<A, T[], U>& other) const {
return !(*this == other);
}
private:
A2 allocator;
std::size_t size;
T** data;
};
template<typename A, typename T, std::size_t N, typename Y>
class allocate_array_helper<A, T[N], Y> {
template<typename A9, typename T9, typename Y9>
friend class allocate_array_helper;
typedef typename A::template rebind<Y> ::other A2;
typedef typename A::template rebind<char>::other A3;
public:
typedef typename A2::value_type value_type;
typedef typename A2::pointer pointer;
typedef typename A2::const_pointer const_pointer;
typedef typename A2::reference reference;
typedef typename A2::const_reference const_reference;
typedef typename A2::size_type size_type;
typedef typename A2::difference_type difference_type;
template<typename U>
struct rebind {
typedef allocate_array_helper<A, T[N], U> other;
};
allocate_array_helper(const A& allocator_, T** data_)
: allocator(allocator_),
data(data_) {
}
template<class U>
allocate_array_helper(const allocate_array_helper<A, T[N], U>& other)
: allocator(other.allocator),
data(other.data) {
}
pointer address(reference value) const {
return allocator.address(value);
}
const_pointer address(const_reference value) const {
return allocator.address(value);
}
size_type max_size() const {
return allocator.max_size();
}
pointer allocate(size_type count, const void* value = 0) {
std::size_t a1 = boost::alignment_of<T>::value;
std::size_t n1 = count * sizeof(Y) + a1 - 1;
char* p1 = A3(allocator).allocate(n1 + N1, value);
char* p2 = p1 + n1;
while (std::size_t(p2) % a1 != 0) {
p2--;
}
*data = reinterpret_cast<T*>(p2);
return reinterpret_cast<Y*>(p1);
}
void deallocate(pointer memory, size_type count) {
std::size_t a1 = boost::alignment_of<T>::value;
std::size_t n1 = count * sizeof(Y) + a1 - 1;
char* p1 = reinterpret_cast<char*>(memory);
A3(allocator).deallocate(p1, n1 + N1);
}
void construct(pointer memory, const Y& value) {
allocator.construct(memory, value);
}
void destroy(pointer memory) {
allocator.destroy(memory);
}
template<typename U>
bool operator==(const allocate_array_helper<A, T[N], U>& other) const {
return allocator == other.allocator;
}
template<typename U>
bool operator!=(const allocate_array_helper<A, T[N], U>& other) const {
return !(*this == other);
}
private:
enum {
N1 = N * sizeof(T)
};
A2 allocator;
T** data;
};
}
}
#endif

View File

@@ -1,124 +0,0 @@
/*
* Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
#include <boost/smart_ptr/detail/array_utility.hpp>
#include <boost/smart_ptr/detail/sp_forward.hpp>
namespace boost {
namespace detail {
template<typename T>
class array_deleter;
template<typename T>
class array_deleter<T[]> {
public:
array_deleter(std::size_t size_)
: size(size_),
object(0) {
}
~array_deleter() {
if (object) {
array_destroy(object, size);
}
}
void init(T* memory) {
array_init(memory, size);
object = memory;
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
void init(T* memory, T&& value) {
array_init_value(memory, size, sp_forward<T>(value));
object = memory;
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename... Args>
void init(T* memory, Args&&... args) {
array_init_args(memory, size, sp_forward<Args>(args)...);
object = memory;
}
#endif
#endif
void init_list(T* memory, const T* list) {
array_init_list(memory, size, list);
object = memory;
}
template<std::size_t M>
void init_list(T* memory, const T* list) {
array_init_list<T, M>(memory, size, list);
object = memory;
}
void noinit(T* memory) {
array_noinit(memory, size);
object = memory;
}
void operator()(const void*) {
if (object) {
array_destroy(object, size);
object = 0;
}
}
private:
std::size_t size;
T* object;
};
template<typename T, std::size_t N>
class array_deleter<T[N]> {
public:
array_deleter()
: object(0) {
}
~array_deleter() {
if (object) {
array_destroy(object, N);
}
}
void init(T* memory) {
array_init(memory, N);
object = memory;
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
void init(T* memory, T&& value) {
array_init_value(memory, N, sp_forward<T>(value));
object = memory;
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename... Args>
void init(T* memory, Args&&... args) {
array_init_args(memory, N, sp_forward<Args>(args)...);
object = memory;
}
#endif
#endif
void init_list(T* memory, const T* list) {
array_init_list(memory, N, list);
object = memory;
}
template<std::size_t M>
void init_list(T* memory, const T* list) {
array_init_list<T, M>(memory, N, list);
object = memory;
}
void noinit(T* memory) {
array_noinit(memory, N);
object = memory;
}
void operator()(const void*) {
if (object) {
array_destroy(object, N);
object = 0;
}
}
private:
T* object;
};
}
}
#endif

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
#include <boost/type_traits/remove_cv.hpp>
namespace boost {
namespace detail {
template<typename T>
struct array_base {
typedef typename boost::remove_cv<T>::type type;
};
template<typename T>
struct array_base<T[]> {
typedef typename array_base<T>::type type;
};
template<typename T, std::size_t N>
struct array_base<T[N]> {
typedef typename array_base<T>::type type;
};
template<typename T>
struct array_total {
enum {
size = 1
};
};
template<typename T, std::size_t N>
struct array_total<T[N]> {
enum {
size = N * array_total<T>::size
};
};
template<typename T>
struct array_inner;
template<typename T>
struct array_inner<T[]> {
typedef T type;
};
template<typename T, std::size_t N>
struct array_inner<T[N]> {
typedef T type;
};
}
}
#endif

View File

@@ -1,178 +0,0 @@
/*
* Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
#include <boost/config.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
namespace boost {
namespace detail {
template<typename T>
inline void array_destroy(T*, std::size_t, boost::true_type) {
}
template<typename T>
inline void array_destroy(T* memory, std::size_t size, boost::false_type) {
for (std::size_t i = size; i > 0; ) {
memory[--i].~T();
}
}
template<typename T>
inline void array_destroy(T* memory, std::size_t size) {
boost::has_trivial_destructor<T> type;
array_destroy(memory, size, type);
}
template<typename T>
inline void array_init(T* memory, std::size_t size, boost::true_type) {
for (std::size_t i = 0; i < size; i++) {
memory[i] = T();
}
}
template<typename T>
inline void array_init(T* memory, std::size_t size, boost::false_type) {
#if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0;
try {
for (; i < size; i++) {
void* p1 = memory + i;
::new(p1) T();
}
} catch (...) {
array_destroy(memory, i);
throw;
}
#else
for (std::size_t i = 0; i < size; i++) {
void* p1 = memory + i;
::new(p1) T();
}
#endif
}
template<typename T>
inline void array_init(T* memory, std::size_t size) {
boost::has_trivial_default_constructor<T> type;
array_init(memory, size, type);
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename T>
inline void array_init_value(T* memory, std::size_t size, T&& value) {
#if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0;
try {
for (; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(value);
}
} catch (...) {
array_destroy(memory, i);
throw;
}
#else
for (std::size_t i = 0; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(value);
}
#endif
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename T, typename... Args>
inline void array_init_args(T* memory, std::size_t size, Args&&... args) {
#if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0;
try {
for (; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(args...);
}
} catch (...) {
array_destroy(memory, i);
throw;
}
#else
for (std::size_t i = 0; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(args...);
}
#endif
}
#endif
#endif
template<typename T>
inline void array_init_list(T* memory, std::size_t size, const T* list) {
#if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0;
try {
for (; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(list[i]);
}
} catch (...) {
array_destroy(memory, i);
throw;
}
#else
for (std::size_t i = 0; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(list[i]);
}
#endif
}
template<typename T, std::size_t N>
inline void array_init_list(T* memory, std::size_t size, const T* list) {
#if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0;
try {
for (; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(list[i % N]);
}
} catch (...) {
array_destroy(memory, i);
throw;
}
#else
for (std::size_t i = 0; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(list[i % N]);
}
#endif
}
template<typename T>
inline void array_noinit(T*, std::size_t, boost::true_type) {
}
template<typename T>
inline void array_noinit(T* memory, std::size_t size, boost::false_type) {
#if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0;
try {
for (; i < size; i++) {
void* p1 = memory + i;
::new(p1) T;
}
} catch (...) {
array_destroy(memory, i);
throw;
}
#else
for (std::size_t i = 0; i < size; i++) {
void* p1 = memory + i;
::new(p1) T;
}
#endif
}
template<typename T>
inline void array_noinit(T* memory, std::size_t size) {
boost::has_trivial_default_constructor<T> type;
array_noinit(memory, size, type);
}
}
}
#endif

View File

@@ -1,119 +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.
//
// Distributed under the 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: (long) the new value of a
//
// --a;
//
// Effects: Atomically decrements the value of a
// Returns: (long) the new value of a
//
// 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/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#ifndef BOOST_HAS_THREADS
namespace boost
{
namespace detail
{
typedef long atomic_count;
}
}
#elif defined(BOOST_AC_USE_PTHREADS)
# include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_AC_USE_PTHREADS
# include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error
#error Unrecognized threading platform
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,157 +0,0 @@
/*
* Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
#define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
#include <boost/type_traits/alignment_of.hpp>
namespace boost {
namespace detail {
template<typename T, typename Y = char>
class make_array_helper;
template<typename T, typename Y>
class make_array_helper<T[], Y> {
template<typename T2, typename Y2>
friend class make_array_helper;
public:
typedef Y value_type;
typedef Y* pointer;
typedef const Y* const_pointer;
typedef Y& reference;
typedef const Y& const_reference;
typedef std::size_t size_type;
typedef ptrdiff_t difference_type;
template<typename U>
struct rebind {
typedef make_array_helper<T[], U> other;
};
make_array_helper(std::size_t size_, T** data_)
: size(sizeof(T) * size_),
data(data_) {
}
template<class U>
make_array_helper(const make_array_helper<T[], U>& other)
: size(other.size),
data(other.data) {
}
pointer address(reference value) const {
return &value;
}
const_pointer address(const_reference value) const {
return &value;
}
size_type max_size() const {
return static_cast<std::size_t>(-1) / sizeof(Y);
}
pointer allocate(size_type count, const void* = 0) {
std::size_t a1 = boost::alignment_of<T>::value;
std::size_t n1 = count * sizeof(Y) + a1 - 1;
void* p1 = ::operator new(n1 + size);
char* p2 = static_cast<char*>(p1) + n1;
while (std::size_t(p2) % a1 != 0) {
p2--;
}
*data = reinterpret_cast<T*>(p2);
return reinterpret_cast<Y*>(p1);
}
void deallocate(pointer memory, size_type) {
void* p1 = memory;
::operator delete(p1);
}
void construct(pointer memory, const Y& value) {
void* p1 = memory;
::new(p1) Y(value);
}
void destroy(pointer memory) {
memory->~Y();
}
template<typename U>
bool operator==(const make_array_helper<T[], U>&) const {
return true;
}
template<typename U>
bool operator!=(const make_array_helper<T[], U>& other) const {
return !(*this == other);
}
private:
std::size_t size;
T** data;
};
template<typename T, std::size_t N, typename Y>
class make_array_helper<T[N], Y> {
template<typename T2, typename Y2>
friend class make_array_helper;
public:
typedef Y value_type;
typedef Y* pointer;
typedef const Y* const_pointer;
typedef Y& reference;
typedef const Y& const_reference;
typedef std::size_t size_type;
typedef ptrdiff_t difference_type;
template<typename U>
struct rebind {
typedef make_array_helper<T[N], U> other;
};
make_array_helper(T** data_)
: data(data_) {
}
template<class U>
make_array_helper(const make_array_helper<T[N], U>& other)
: data(other.data) {
}
pointer address(reference value) const {
return &value;
}
const_pointer address(const_reference value) const {
return &value;
}
size_type max_size() const {
return static_cast<std::size_t>(-1) / sizeof(Y);
}
pointer allocate(size_type count, const void* = 0) {
std::size_t a1 = boost::alignment_of<T>::value;
std::size_t n1 = count * sizeof(Y) + a1 - 1;
void* p1 = ::operator new(n1 + N1);
char* p2 = static_cast<char*>(p1) + n1;
while (std::size_t(p2) % a1 != 0) {
p2--;
}
*data = reinterpret_cast<T*>(p2);
return reinterpret_cast<Y*>(p1);
}
void deallocate(pointer memory, size_type) {
void* p1 = memory;
::operator delete(p1);
}
void construct(pointer memory, const Y& value) {
void* p1 = memory;
::new(p1) Y(value);
}
void destroy(pointer memory) {
memory->~Y();
}
template<typename U>
bool operator==(const make_array_helper<T[N], U>&) const {
return true;
}
template<typename U>
bool operator!=(const make_array_helper<T[N], U>& other) const {
return !(*this == other);
}
private:
enum {
N1 = N * sizeof(T)
};
T** data;
};
}
}
#endif

View File

@@ -1,63 +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 )
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;
}

View File

@@ -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

View File

@@ -1,603 +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/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
#if !defined( BOOST_NO_CXX11_SMART_PTR )
# include <boost/utility/addressof.hpp>
#endif
namespace boost
{
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
{
};
#if !defined( BOOST_NO_CXX11_SMART_PTR )
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;
};
#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 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;
typedef typename A::template rebind< impl_type >::other A2;
A2 a2( a );
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
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, static_cast< impl_type* >( 0 ) );
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;
typedef typename A::template rebind< impl_type >::other A2;
A2 a2( a );
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
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, static_cast< impl_type* >( 0 ) );
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
~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
#ifdef __BORLANDC__
# pragma warn .8027 // Functions containing try are not expanded inline
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED

View File

@@ -1,91 +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>
#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

View File

@@ -1,79 +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, 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)
//
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#if defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.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( __SNC__ )
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
#elif defined(__HP_aCC) && defined(__ia64)
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
#elif defined( __IBMCPP__ ) && defined( __powerpc )
# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
#elif defined( _AIX )
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
#elif !defined( BOOST_HAS_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#else
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,39 +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 )
template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
{
return static_cast< T&& >( t );
}
#endif
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED

View File

@@ -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( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
# define BOOST_SP_HAS_SYNC
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
# define BOOST_SP_HAS_SYNC
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
#define BOOST_SP_HAS_SYNC
#if defined( __arm__ ) || defined( __armel__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __hppa ) || defined( __hppa__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __m68k__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sh__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
#undef BOOST_SP_HAS_SYNC
#endif
#endif
#endif // #ifndef BOOST_SP_NO_SYNC
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED

View File

@@ -1,31 +0,0 @@
/*
* Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
#include <boost/smart_ptr/shared_ptr.hpp>
namespace boost {
namespace detail {
template<typename T>
struct sp_if_array;
template<typename T>
struct sp_if_array<T[]> {
typedef boost::shared_ptr<T[]> type;
};
template<typename T>
struct sp_if_size_array;
template<typename T, std::size_t N>
struct sp_if_size_array<T[N]> {
typedef boost::shared_ptr<T[N]> type;
};
}
}
#endif

View File

@@ -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( __clang__ ) && !defined( _LIBCPP_VERSION ) && !defined( BOOST_NO_CXX11_DECLTYPE )
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

View File

@@ -1,56 +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_PTHREADS )
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/spinlock_w32.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
#elif !defined(BOOST_HAS_THREADS)
# include <boost/smart_ptr/detail/spinlock_nt.hpp>
#else
# error Unrecognized threading platform
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED

View File

@@ -1,120 +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;
}
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

View File

@@ -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

View File

@@ -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 I > 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 I > spinlock spinlock_pool< I >::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

View File

@@ -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

View File

@@ -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

View File

@@ -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/detail/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_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

View File

@@ -1,148 +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
//
// 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>
// 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 )
extern "C" void __stdcall Sleep( unsigned long ms );
#endif
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 )
{
Sleep( 0 );
}
else
{
Sleep( 1 );
}
}
} // namespace detail
} // namespace boost
#elif defined( BOOST_HAS_PTHREADS )
#include <sched.h>
#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

View File

@@ -1,144 +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 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_weak_once() const
{
if( weak_this_.expired() )
{
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> shared_from_this()
{
init_weak_once();
return shared_ptr<void>( weak_this_ );
}
shared_ptr<const void> shared_from_this() const
{
init_weak_once();
return shared_ptr<const void>( weak_this_ );
}
// Note: invoked automatically by shared_ptr; do not call
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) 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> weak_this_;
private:
mutable shared_ptr<void> 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_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

View File

@@ -1,79 +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/assert.hpp>
#include <boost/config.hpp>
namespace boost
{
template<class T> class enable_shared_from_this
{
protected:
enable_shared_from_this() BOOST_NOEXCEPT
{
}
enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT
{
}
enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT
{
return *this;
}
~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
{
}
public:
shared_ptr<T> shared_from_this()
{
shared_ptr<T> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
shared_ptr<T const> shared_from_this() const
{
shared_ptr<T const> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
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

View File

@@ -1,324 +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/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;
intrusive_ptr() BOOST_NOEXCEPT : px( 0 )
{
}
intrusive_ptr( T * p, bool add_ref = true ): px( p )
{
if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
#else
intrusive_ptr( intrusive_ptr<U> const & rhs )
#endif
: px( rhs.get() )
{
if( px != 0 ) intrusive_ptr_add_ref( px );
}
#endif
intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
{
if( px != 0 ) intrusive_ptr_add_ref( px );
}
~intrusive_ptr()
{
if( px != 0 ) intrusive_ptr_release( px );
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
#endif
// Move support
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px )
{
rhs.px = 0;
}
intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT
{
this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
return *this;
}
#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 );
}
T * get() const BOOST_NOEXCEPT
{
return px;
}
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

View File

@@ -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 --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_

View File

@@ -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

View File

@@ -1,247 +0,0 @@
/*
* Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/array_deleter.hpp>
#include <boost/smart_ptr/detail/array_traits.hpp>
#include <boost/smart_ptr/detail/make_array_helper.hpp>
#include <boost/smart_ptr/detail/sp_if_array.hpp>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
namespace boost {
template<typename T>
inline typename boost::detail::sp_if_array<T>::type
make_shared(std::size_t size) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
T1* p1 = 0;
T2* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2);
return boost::shared_ptr<T>(s1, p1);
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename T, typename... Args>
inline typename boost::detail::sp_if_array<T>::type
make_shared(std::size_t size, Args&&... args) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
T1* p1 = 0;
T2* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
return boost::shared_ptr<T>(s1, p1);
}
template<typename T, typename... Args>
inline typename boost::detail::sp_if_size_array<T>::type
make_shared(Args&&... args) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
enum {
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
boost::detail::make_array_helper<T2[N]> a1(&p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
return boost::shared_ptr<T>(s1, p1);
}
#endif
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
template<typename T>
inline typename boost::detail::sp_if_size_array<T>::type
make_shared(const T& list) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3;
enum {
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
T3* p3 = 0;
boost::detail::make_array_helper<T2[N]> a1(&p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p3 = reinterpret_cast<T3*>(list);
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init_list(p2, p3);
return boost::shared_ptr<T>(s1, p1);
}
template<typename T>
inline typename boost::detail::sp_if_array<T>::type
make_shared(std::size_t size,
const typename boost::detail::array_inner<T>::type& list) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3;
enum {
M = boost::detail::array_total<T1>::size
};
T1* p1 = 0;
T2* p2 = 0;
T3* p3 = 0;
std::size_t n1 = M * size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p3 = reinterpret_cast<T3*>(list);
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->template init_list<M>(p2, p3);
return boost::shared_ptr<T>(s1, p1);
}
template<typename T>
inline typename boost::detail::sp_if_size_array<T>::type
make_shared(const typename boost::detail::array_inner<T>::type& list) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3;
enum {
M = boost::detail::array_total<T1>::size,
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
T3* p3 = 0;
boost::detail::make_array_helper<T2[N]> a1(&p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p3 = reinterpret_cast<T3*>(list);
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->template init_list<M>(p2, p3);
return boost::shared_ptr<T>(s1, p1);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template<typename T>
inline typename boost::detail::sp_if_array<T>::type
make_shared(std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3;
T1* p1 = 0;
T2* p2 = 0;
T3* p3 = 0;
std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p3 = reinterpret_cast<T3*>(list.begin());
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init_list(p2, p3);
return boost::shared_ptr<T>(s1, p1);
}
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename T>
inline typename boost::detail::sp_if_array<T>::type
make_shared(std::size_t size,
typename boost::detail::array_base<T>::type&& value) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
T1* p1 = 0;
T2* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2, boost::detail::sp_forward<T2>(value));
return boost::shared_ptr<T>(s1, p1);
}
template<typename T>
inline typename boost::detail::sp_if_size_array<T>::type
make_shared(typename boost::detail::array_base<T>::type&& value) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
enum {
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
boost::detail::make_array_helper<T2[N]> a1(&p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->init(p2, boost::detail::sp_forward<T2>(value));
return boost::shared_ptr<T>(s1, p1);
}
#endif
#endif
template<typename T>
inline typename boost::detail::sp_if_array<T>::type
make_shared_noinit(std::size_t size) {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
T1* p1 = 0;
T2* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
boost::detail::array_deleter<T2[]> d1(n1);
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->noinit(p2);
return boost::shared_ptr<T>(s1, p1);
}
template<typename T>
inline typename boost::detail::sp_if_size_array<T>::type
make_shared_noinit() {
typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2;
enum {
N = boost::detail::array_total<T>::size
};
T1* p1 = 0;
T2* p2 = 0;
boost::detail::make_array_helper<T2[N]> a1(&p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
d2->noinit(p2);
return boost::shared_ptr<T>(s1, p1);
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,57 +0,0 @@
#ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
#define BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
//
// owner_less.hpp
//
// Copyright (c) 2008 Frank Mori Hess
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/smart_ptr/smart_ptr.htm for documentation.
//
#include <functional>
namespace boost
{
template<typename T> class shared_ptr;
template<typename T> class weak_ptr;
namespace detail
{
template<typename T, typename U>
struct generic_owner_less : public std::binary_function<T, T, bool>
{
bool operator()(const T &lhs, const T &rhs) const
{
return lhs.owner_before(rhs);
}
bool operator()(const T &lhs, const U &rhs) const
{
return lhs.owner_before(rhs);
}
bool operator()(const U &lhs, const T &rhs) const
{
return lhs.owner_before(rhs);
}
};
} // namespace detail
template<typename T> struct owner_less;
template<typename T>
struct owner_less<shared_ptr<T> >:
public detail::generic_owner_less<shared_ptr<T>, weak_ptr<T> >
{};
template<typename T>
struct owner_less<weak_ptr<T> >:
public detail::generic_owner_less<weak_ptr<T>, shared_ptr<T> >
{};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED

View File

@@ -1,132 +0,0 @@
#ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
#define BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
//
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/detail/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t
namespace boost
{
// Debug hooks
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_array_constructor_hook(void * p);
void sp_array_destructor_hook(void * p);
#endif
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
// is guaranteed, either on destruction of the scoped_array or via an explicit
// reset(). Use shared_array or std::vector if your needs are more complex.
template<class T> class scoped_array // noncopyable
{
private:
T * px;
scoped_array(scoped_array const &);
scoped_array & operator=(scoped_array const &);
typedef scoped_array<T> this_type;
void operator==( scoped_array const& ) const;
void operator!=( scoped_array const& ) const;
public:
typedef T element_type;
explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_array_constructor_hook( px );
#endif
}
~scoped_array() // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_array_destructor_hook( px );
#endif
boost::checked_array_delete( px );
}
void reset(T * p = 0) // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
T & operator[](std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
{
BOOST_ASSERT( px != 0 );
BOOST_ASSERT( i >= 0 );
return px[i];
}
T * get() const BOOST_NOEXCEPT
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
void swap(scoped_array & b) BOOST_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
px = tmp;
}
};
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class T> inline bool operator==( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_NOEXCEPT
{
a.swap(b);
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED

View File

@@ -1,157 +0,0 @@
#ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
//
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/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 * px;
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
typedef scoped_ptr<T> this_type;
void operator==( scoped_ptr const& ) const;
void operator!=( scoped_ptr const& ) const;
public:
typedef T element_type;
explicit scoped_ptr( T * p = 0 ): px( p ) // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px );
#endif
}
#ifndef BOOST_NO_AUTO_PTR
explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px );
#endif
}
#endif
~scoped_ptr() // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px );
#endif
boost::checked_delete( px );
}
void reset(T * p = 0) // never throws
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
T & operator*() const // never throws
{
BOOST_ASSERT( px != 0 );
return *px;
}
T * operator->() const // never throws
{
BOOST_ASSERT( px != 0 );
return px;
}
T * get() const BOOST_NOEXCEPT
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
void swap(scoped_ptr & b) BOOST_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
px = tmp;
}
};
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
{
a.swap(b);
}
// get_pointer(p) is a generic way to say p.get()
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
{
return p.get();
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED

View File

@@ -1,290 +0,0 @@
#ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
#define BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
//
// shared_array.hpp
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002, 2012 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
//
#include <boost/config.hpp> // for broken compiler workarounds
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/smart_ptr/detail/shared_array_nmt.hpp>
#else
#include <memory> // TR1 cyclic inclusion fix
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/detail/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t
#include <algorithm> // for std::swap
#include <functional> // for std::less
namespace boost
{
//
// shared_array
//
// shared_array extends shared_ptr to arrays.
// The array pointed to is deleted when the last shared_array pointing to it
// is destroyed or reset.
//
template<class T> class shared_array
{
private:
// Borland 5.5.1 specific workarounds
typedef checked_array_deleter<T> deleter;
typedef shared_array<T> this_type;
public:
typedef T element_type;
shared_array() BOOST_NOEXCEPT : px( 0 ), pn()
{
}
template<class Y>
explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
{
boost::detail::sp_assert_convertible< Y[], T[] >();
}
//
// Requirements: D's copy constructor must not throw
//
// shared_array will release p by calling d(p)
//
template<class Y, class D> shared_array( Y * p, D d ): px( p ), pn( p, d )
{
boost::detail::sp_assert_convertible< Y[], T[] >();
}
// As above, but with allocator. A's copy constructor shall not throw.
template<class Y, class D, class A> shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a )
{
boost::detail::sp_assert_convertible< Y[], T[] >();
}
// generated copy constructor, destructor are fine...
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// ... except in C++0x, move disables the implicit copy
shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
{
}
shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn()
{
pn.swap( r.pn );
r.px = 0;
}
#endif
// conversion
template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
shared_array( shared_array<Y> const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() )
#else
shared_array( shared_array<Y> const & r )
#endif
BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws
{
boost::detail::sp_assert_convertible< Y[], T[] >();
}
// aliasing
template< class Y >
shared_array( shared_array<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
{
}
// assignment
shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT
{
this_type( r ).swap( *this );
return *this;
}
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
template<class Y>
shared_array & operator=( shared_array<Y> const & r ) BOOST_NOEXCEPT
{
this_type( r ).swap( *this );
return *this;
}
#endif
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT
{
this_type( static_cast< shared_array && >( r ) ).swap( *this );
return *this;
}
template<class Y>
shared_array & operator=( shared_array<Y> && r ) BOOST_NOEXCEPT
{
this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
return *this;
}
#endif
void reset() BOOST_NOEXCEPT
{
this_type().swap( *this );
}
template<class Y> void reset( Y * p ) // Y must be complete
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type( p ).swap( *this );
}
template<class Y, class D> void reset( Y * p, D d )
{
this_type( p, d ).swap( *this );
}
template<class Y, class D, class A> void reset( Y * p, D d, A a )
{
this_type( p, d, a ).swap( *this );
}
template<class Y> void reset( shared_array<Y> const & r, element_type * p )
{
this_type( r, p ).swap( *this );
}
T & operator[] (std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
{
BOOST_ASSERT(px != 0);
BOOST_ASSERT(i >= 0);
return px[i];
}
T * get() const BOOST_NOEXCEPT
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
bool unique() const BOOST_NOEXCEPT
{
return pn.unique();
}
long use_count() const BOOST_NOEXCEPT
{
return pn.use_count();
}
void swap(shared_array<T> & other) BOOST_NOEXCEPT
{
std::swap(px, other.px);
pn.swap(other.pn);
}
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
{
return pn.get_deleter( ti );
}
private:
template<class Y> friend class shared_array;
T * px; // contained pointer
detail::shared_count pn; // reference counter
}; // shared_array
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
{
return a.get() == b.get();
}
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
{
return a.get() != b.get();
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
{
return std::less<T*>()(a.get(), b.get());
}
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_NOEXCEPT
{
a.swap(b);
}
template< class D, class T > D * get_deleter( shared_array<T> const & p )
{
return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
}
} // namespace boost
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@@ -1,253 +0,0 @@
#ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
//
// weak_ptr.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)
//
// See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
//
#include <memory> // boost.TR1 include order fix
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
namespace boost
{
template<class T> class weak_ptr
{
private:
// Borland 5.5.1 specific workarounds
typedef weak_ptr<T> this_type;
public:
typedef typename boost::detail::sp_element< T >::type element_type;
weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+
{
}
// generated copy constructor, assignment, destructor are fine...
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// ... except in C++0x, move disables the implicit copy
weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
{
}
weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT
{
px = r.px;
pn = r.pn;
return *this;
}
#endif
//
// The "obvious" converting constructor implementation:
//
// template<class Y>
// weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
// {
// }
//
// has a serious problem.
//
// r.px may already have been invalidated. The px(r.px)
// conversion may require access to *r.px (virtual inheritance).
//
// It is not possible to avoid spurious access violations since
// in multithreaded programs r.px may be invalidated at any point.
//
template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
#else
weak_ptr( weak_ptr<Y> const & r )
#endif
BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn)
{
boost::detail::sp_assert_convertible< Y, T >();
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
#else
weak_ptr( weak_ptr<Y> && r )
#endif
BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
{
boost::detail::sp_assert_convertible< Y, T >();
r.px = 0;
}
// for better efficiency in the T == Y case
weak_ptr( weak_ptr && r )
BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
{
r.px = 0;
}
// for better efficiency in the T == Y case
weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
{
this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
return *this;
}
#endif
template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
#else
weak_ptr( shared_ptr<Y> const & r )
#endif
BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
{
boost::detail::sp_assert_convertible< Y, T >();
}
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
template<class Y>
weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT
{
boost::detail::sp_assert_convertible< Y, T >();
px = r.lock().get();
pn = r.pn;
return *this;
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y>
weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
{
this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
return *this;
}
#endif
template<class Y>
weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT
{
boost::detail::sp_assert_convertible< Y, T >();
px = r.px;
pn = r.pn;
return *this;
}
#endif
shared_ptr<T> lock() const BOOST_NOEXCEPT
{
return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
}
long use_count() const BOOST_NOEXCEPT
{
return pn.use_count();
}
bool expired() const BOOST_NOEXCEPT
{
return pn.use_count() == 0;
}
bool _empty() const // extension, not in std::weak_ptr
{
return pn.empty();
}
void reset() BOOST_NOEXCEPT // never throws in 1.30+
{
this_type().swap(*this);
}
void swap(this_type & other) BOOST_NOEXCEPT
{
std::swap(px, other.px);
pn.swap(other.pn);
}
template<typename Y>
void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
{
px = px2;
pn = r.pn;
}
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
{
return pn < rhs.pn;
}
template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
{
return pn < rhs.pn;
}
// 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 weak_ptr;
template<class Y> friend class shared_ptr;
#endif
element_type * px; // contained pointer
boost::detail::weak_count pn; // reference counter
}; // weak_ptr
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_NOEXCEPT
{
return a.owner_before( b );
}
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_NOEXCEPT
{
a.swap(b);
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED

View File

@@ -6,13 +6,187 @@
//
// 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
// Distributed under the 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/weak_ptr.htm for documentation.
//
#include <boost/smart_ptr/weak_ptr.hpp>
#include <boost/shared_ptr.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
namespace boost
{
template<class T> class weak_ptr
{
private:
// Borland 5.5.1 specific workarounds
typedef weak_ptr<T> this_type;
public:
typedef T element_type;
weak_ptr(): px(0), pn() // never throws in 1.30+
{
}
// generated copy constructor, assignment, destructor are fine
//
// The "obvious" converting constructor implementation:
//
// template<class Y>
// weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
// {
// }
//
// has a serious problem.
//
// r.px may already have been invalidated. The px(r.px)
// conversion may require access to *r.px (virtual inheritance).
//
// It is not possible to avoid spurious access violations since
// in multithreaded programs r.px may be invalidated at any point.
//
template<class Y>
weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
{
px = r.lock().get();
}
template<class Y>
weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
{
}
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
template<class Y>
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
{
px = r.lock().get();
pn = r.pn;
return *this;
}
template<class Y>
weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
{
px = r.px;
pn = r.pn;
return *this;
}
#endif
shared_ptr<T> lock() const // never throws
{
#if defined(BOOST_HAS_THREADS)
// optimization: avoid throw overhead
if(expired())
{
return shared_ptr<element_type>();
}
try
{
return shared_ptr<element_type>(*this);
}
catch(bad_weak_ptr const &)
{
// Q: how can we get here?
// A: another thread may have invalidated r after the use_count test above.
return shared_ptr<element_type>();
}
#else
// optimization: avoid try/catch overhead when single threaded
return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
#endif
}
long use_count() const // never throws
{
return pn.use_count();
}
bool expired() const // never throws
{
return pn.use_count() == 0;
}
void reset() // never throws in 1.30+
{
this_type().swap(*this);
}
void swap(this_type & other) // never throws
{
std::swap(px, other.px);
pn.swap(other.pn);
}
void _internal_assign(T * px2, detail::shared_count const & pn2)
{
px = px2;
pn = pn2;
}
template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const
{
return pn < rhs.pn;
}
// 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 weak_ptr;
template<class Y> friend class shared_ptr;
#endif
T * px; // contained pointer
detail::weak_count pn; // reference counter
}; // weak_ptr
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
{
return a._internal_less(b);
}
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
{
a.swap(b);
}
// deprecated, provided for backward compatibility
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
{
return r.lock();
}
} // namespace boost
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
#endif // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED

View File

@@ -7,9 +7,3 @@ Automatic redirection failed, please go to
<a href="smart_ptr.htm">smart_ptr.htm</a>.
</body>
</html>
<!--
<09> Copyright Beman Dawes, 2001
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
-->

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
border="0"></A>intrusive_ptr class template</h1>
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle">intrusive_ptr
class template</h1>
<p>
<A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
@@ -24,20 +24,18 @@
compilers that support argument-dependent lookup, <STRONG>intrusive_ptr_add_ref</STRONG>
and <STRONG>intrusive_ptr_release</STRONG> should be defined in the namespace
that corresponds to their parameter; otherwise, the definitions need to go in
namespace <STRONG>boost</STRONG>. The library provides a helper base class template
<STRONG><a href="intrusive_ref_counter.html">intrusive_ref_counter</a></STRONG> which may
help adding support for <STRONG>intrusive_ptr</STRONG> to user&apos;s types.</p>
namespace <STRONG>boost</STRONG>.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <STRONG>intrusive_ptr&lt;T&gt;</STRONG> can be implicitly converted to <STRONG>intrusive_ptr&lt;U&gt;</STRONG>
whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.</p>
<P>The main reasons to use <STRONG>intrusive_ptr</STRONG> are:</P>
<UL>
<LI>
Some existing frameworks or OSes provide objects with embedded reference
counts;
Some existing frameworks or OSes provide objects with embedded reference
counts;</LI>
<LI>
The memory footprint of <STRONG>intrusive_ptr</STRONG>
is the same as the corresponding raw pointer;
The memory footprint of <STRONG>intrusive_ptr</STRONG> is the same as the
corresponding raw pointer;</LI>
<LI>
<STRONG>intrusive_ptr&lt;T&gt;</STRONG> can be constructed from an arbitrary
raw pointer of type <STRONG>T *</STRONG>.</LI></UL>
@@ -63,10 +61,7 @@
intrusive_ptr &amp; <A href="#assignment" >operator=</A>(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; <A href="#assignment" >operator=</A>(intrusive_ptr&lt;Y&gt; const &amp; r);
intrusive_ptr &amp; <A href="#assignment" >operator=</A>(T * r);
void <a href="#reset" >reset</a>();
void <a href="#reset" >reset</a>(T * r);
template&lt;class Y&gt; intrusive_ptr &amp; <A href="#assignment" >operator=</A>(T * r);
T &amp; <A href="#indirection" >operator*</A>() const; // never throws
T * <A href="#indirection" >operator-&gt;</A>() const; // never throws
@@ -132,8 +127,8 @@
<p><b>Effects:</b> <code>if(p != 0 &amp;&amp; add_ref) intrusive_ptr_add_ref(p);</code>.</p>
<p><b>Postconditions:</b> <code>get() == p</code>.</p>
</blockquote>
<pre>intrusive_ptr(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr(intrusive_ptr&lt;Y&gt; const &amp; r);</pre>
<pre>intrusive_ptr(intrusive_ptr const &amp; r); // never throws
template&lt;class Y&gt; intrusive_ptr(intrusive_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Effects:</b> <code>if(r.get() != 0) intrusive_ptr_add_ref(r.get());</code>.</p>
<p><b>Postconditions:</b> <code>get() == r.get()</code>.</p>
@@ -144,22 +139,13 @@ template&lt;class Y&gt; intrusive_ptr(intrusive_ptr&lt;Y&gt; const &amp; r);</pr
<P><B>Effects:</B> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</P>
</BLOCKQUOTE>
<H3><a name="assignment">assignment</a></H3>
<pre>intrusive_ptr &amp; operator=(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; operator=(intrusive_ptr&lt;Y&gt; const &amp; r);
<pre>intrusive_ptr &amp; operator=(intrusive_ptr const &amp; r); // never throws
template&lt;class Y&gt; intrusive_ptr &amp; operator=(intrusive_ptr&lt;Y&gt; const &amp; r); // never throws
intrusive_ptr &amp; operator=(T * r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
<P><B>Returns:</B> <code>*this</code>.</P>
</BLOCKQUOTE>
<H3><a name="reset">reset</a></H3>
<pre>void reset();</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</P>
</BLOCKQUOTE>
<pre>void reset(T * r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre>
<blockquote>
@@ -210,26 +196,26 @@ intrusive_ptr &amp; operator=(T * r);</pre>
<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator==(intrusive_ptr&lt;T&gt; const &amp; a, U * b); // never throws</pre>
<pre>template&lt;class T&gt;
bool operator==(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() == b</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator!=(intrusive_ptr&lt;T&gt; const &amp; a, U * b); // never throws</pre>
<pre>template&lt;class T&gt;
bool operator!=(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() != b</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator==(T * a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<pre>template&lt;class T&gt;
bool operator==(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a == b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator!=(T * a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<pre>template&lt;class T&gt;
bool operator!=(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a != b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
@@ -292,8 +278,9 @@ intrusive_ptr &amp; operator=(T * r);</pre>
<p>
$Date$</p>
<p>
<small>Copyright <20> 2003-2005 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>
<small>Copyright <20> 2003 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>

View File

@@ -1,95 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>intrusive_ref_counter</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
border="0"></A>basic_intrusive_ref_counter class template</h1>
<p>
<A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#Members">Members</A><br>
</p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <STRONG>intrusive_ref_counter</STRONG> class template implements a reference counter for a derived
user&apos;s class that is intended to be used with <STRONG><a href="intrusive_ptr.html">intrusive_ptr</a></STRONG>.
The base class has associated <STRONG>intrusive_ptr_add_ref</STRONG> and <STRONG>intrusive_ptr_release</STRONG> functions
which modify the reference counter as needed and destroy the user's object when the counter drops to zero.</p>
<p>The class template is parameterized on <STRONG>DerivedT</STRONG> and <STRONG>CounterPolicyT</STRONG> parameters.
The first parameter is the user&apos;s class that derives from <STRONG>intrusive_ref_counter</STRONG>. This type
is needed in order to destroy the object correctly when there are no references to it left.</p>
<p>The second parameter is a policy that defines the nature of the reference counter.
Boost.SmartPtr provides two such policies: <STRONG>thread_unsafe_counter</STRONG> and <STRONG>thread_safe_counter</STRONG>. The former
instructs the <STRONG>intrusive_ref_counter</STRONG> base class to use a counter only suitable for a single-threaded use.
Pointers to a single object that uses this kind of reference counter must not be used in different threads. The latter policy
makes the reference counter thread-safe, unless the target platform doesn't support threading. Since in modern systems support for
threading is common, the default counter policy is <STRONG>thread_safe_counter</STRONG>.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
struct thread_unsafe_counter;
struct thread_safe_counter;
template&lt;class DerivedT, class CounterPolicyT = thread_safe_counter&gt;
class intrusive_ref_counter
{
public:
<A href="#constructors" >intrusive_ref_counter</A>() = noexcept;
<A href="#constructors" >intrusive_ref_counter</A>(intrusive_ref_counter const &amp; r) = noexcept;
intrusive_ref_counter &amp; <A href="#assignment" >operator=</A>(intrusive_ref_counter const &amp; r) noexcept;
unsigned int <a href="#use_count" >use_count</a>() const noexcept;
protected:
<A href="#destructor" >~intrusive_ref_counter</A>() = default;
};
}</pre>
<h2><a name="Members">Members</a></h2>
<h3><a name="constructors">constructors</a></h3>
<pre>intrusive_ref_counter();</pre>
<blockquote>
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
</blockquote>
<pre>intrusive_ref_counter(intrusive_ref_counter const &amp;);</pre>
<blockquote>
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
</blockquote>
<h3><a name="destructor">destructor</a></h3>
<pre>~intrusive_ref_counter();</pre>
<BLOCKQUOTE>
<p><b>Throws:</b> nothing.</p>
<P><B>Effects:</B> Destroys the counter object.</P>
<P><B>Notes:</B> The destructor is protected so that the object can only be destroyed through the <STRONG>DerivedT</STRONG> class.</P>
</BLOCKQUOTE>
<H3><a name="assignment">assignment</a></H3>
<pre>intrusive_ref_counter &amp; operator=(intrusive_ref_counter const &amp; r) noexcept;</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Does nothing, reference counter is not modified.</P>
<P><B>Returns:</B> <code>*this</code>.</P>
</BLOCKQUOTE>
<H3><a name="use_count">use_count</a></H3>
<pre>unsigned int use_count() const noexcept;</pre>
<BLOCKQUOTE>
<p><b>Returns:</b> The current value of the reference counter.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The returned value may not be actual in multi-threaded applications.</P>
</BLOCKQUOTE>
<hr>
<p>
$Date$</p>
<p>
<small>Copyright <20> 2013 Andrey Semashev. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@@ -1,119 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>make_shared and allocate_shared</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
border="0"></A>make_shared and allocate_shared function templates</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#functions">Free Functions</A><br>
<A href="#example">Example</A><br>
<h2><a name="Introduction">Introduction</a></h2>
<p>Consistent use of <a href="shared_ptr.htm"><code>shared_ptr</code></a>
can eliminate the need to use an explicit <code>delete</code>,
but alone it provides no support in avoiding explicit <code>new</code>.
There have been repeated requests from users for a factory function that creates
an object of a given type and returns a <code>shared_ptr</code> to it.
Besides convenience and style, such a function is also exception safe and
considerably faster because it can use a single allocation for both the object
and its corresponding control block, eliminating a significant portion of
<code>shared_ptr</code>'s construction overhead.
This eliminates one of the major efficiency complaints about <code>shared_ptr</code>.
</p>
<p>The header file &lt;boost/make_shared.hpp&gt; provides a family of overloaded function templates,
<code>make_shared</code> and <code>allocate_shared</code>, to address this need.
<code>make_shared</code> uses the global operator <code>new</code> to allocate memory,
whereas <code>allocate_shared</code> uses an user-supplied allocator, allowing finer control.</p>
<p>
The rationale for choosing the name <code>make_shared</code> is that the expression
<code>make_shared&lt;Widget&gt;()</code> can be read aloud and conveys the intended meaning.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;typename T&gt; class shared_ptr;
template&lt;typename T&gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>();
template&lt;typename T, typename A&gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; );
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Args &amp;&amp; ... args );
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Args &amp;&amp; ... args );
#else // no C++0X support
template&lt;typename T, typename Arg1 &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1 );
template&lt;typename T, typename Arg1, typename Arg2 &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2 );
// ...
template&lt;typename T, typename Arg1, typename Arg2, ..., typename ArgN &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2, ..., ArgN const &amp; argN );
template&lt;typename T, typename A, typename Arg1 &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Arg1 const &amp; arg1 );
template&lt;typename T, typename A, typename Arg1, typename Arg2 &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2 );
// ...
template&lt;typename T, typename A, typename Arg1, typename Arg2, ..., typename ArgN &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Arg1 const &amp; arg1, Arg2 const &amp; arg2, ..., ArgN const &amp; argN );
#endif
}</pre>
<h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;class T, class... Args&gt;
shared_ptr&lt;T&gt; make_shared( Args &amp;&amp; ... args );
template&lt;class T, class A, class... Args&gt;
shared_ptr&lt;T&gt; allocate_shared( A const &amp; a, Args &amp;&amp; ... args );</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>,
where <code>pv</code> is a <code>void*</code> pointing to storage suitable
to hold an object of type <code>T</code>,
shall be well-formed. <code>A</code> shall be an <em>Allocator</em>,
as described in section 20.1.5 (<stong>Allocator requirements</strong>) of the C++ Standard.
The copy constructor and destructor of <code>A</code> shall not throw.</p>
<p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code>
and constructs an object in it via the placement new expression <code>new( pv ) T()</code>
or <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>.
<code>allocate_shared</code> uses a copy of <code>a</code> to allocate memory.
If an exception is thrown, has no effect.</p>
<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and owns the address
of the newly constructed object of type <code>T</code>.</p>
<p><b>Postconditions:</b> <code>get() != 0 &amp;&amp; use_count() == 1</code>.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <code>A::allocate</code>
or the constructor of <code>T</code>.</p>
<p><b>Notes:</b> This implementation allocates the memory required for the
returned <code>shared_ptr</code> and an object of type <code>T</code> in a single
allocation. This provides efficiency equivalent to an intrusive smart pointer.</p>
<p>The prototypes shown above are used if your compiler supports rvalue references
and variadic templates. They perfectly forward the <code>args</code> parameters to
the constructors of <code>T</code>.</p>
<p>Otherwise, the implementation will fall back on
forwarding the arguments to the constructors of <code>T</code> as const references.
If you need to pass a non-const reference to a constructor of <code>T</code>,
you may do so by wrapping the parameter in a call to <code>boost::ref</code>.
In addition, you will be
limited to a maximum of 9 arguments (not counting the allocator argument of
allocate_shared).</p>
</blockquote>
<h2><a name="example">Example</a></h2>
<pre>boost::shared_ptr&lt;std::string&gt; x = boost::make_shared&lt;std::string&gt;("hello, world!");
std::cout << *x;</pre>
<hr>
<p>
$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $</p>
<p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
Distributed under the Boost Software License,
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@@ -1,257 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>make_shared and allocate_shared</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">make_shared and allocate_shared
for arrays</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#functions">Free Functions</A><br>
<A href="#example">Example</A><br>
<A href="#history">History</A><br></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>Originally the Boost function templates <code>make_shared</code> and
<code>allocate_shared</code> were for efficient allocation of single
objects only. There was a need to have efficient, single, allocation of
arrays. One criticism of <a href="shared_array.htm">shared_array</a> was
always the lack of a <a href="make_shared.html">make_shared</a> utility
which ensures only a single allocation for an array.</p>
<p>The header files &lt;boost/smart_ptr/make_shared_array.hpp&gt; and
&lt;boost/smart_ptr/allocate_shared_array.hpp&gt; provide new function
templates, <code>make_shared</code> and <code>allocate_shared</code>,
to address this need. <code>make_shared</code> uses the global
operator <code>new</code> to allocate memory, whereas
<code>allocate_shared</code> uses an user-supplied allocator,
allowing finer control.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size);
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) &amp;&amp; !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, Args&amp;&amp;... args);
template&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, Args&amp;&amp;... args);
#endif
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
template&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(const T (&amp;list)[N]);
template&lt;typename U, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, const T (&amp;list)[N]);
template&lt;typename U, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;T[&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(initializer_list&lt;T&gt; list);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, initializer_list&lt;T&gt; list);
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, T&amp;&amp; value);
template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, T&amp;&amp; value);
#endif
#endif
template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>(size_t size);
template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>();
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator, size_t size);
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator);
}</pre>
<h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared(size_t size, Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, Args&amp;&amp;... args);</pre>
<blockquote>
<p><b>Requires:</b> The expression
<code>new(pointer) T(forward&lt;Args&gt;(args)...)</code>, where
<code>pointer</code> is a <code>void*</code> pointing to storage
suitable to hold an object of type <code>T</code>, shall be
well-formed. <code>A</code> shall be an <em>Allocator</em>, as
described in section 20.1.5 (<strong>Allocator requirements</strong>)
of the C++ Standard. The copy constructor and destructor of
<code>A</code> shall not throw.</p>
<p><b>Effects:</b> Allocates memory suitable for an array of type
<code>T</code> and size <code>size</code> and constructs an array
of objects in it via the placement new expression
<code>new(pointer) T()</code> or
<code>new(pointer) T(args...)</code>.
<code>allocate_shared</code> uses a copy of
<code>allocator</code> to allocate memory. If an exception is thrown,
has no effect.</p>
<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and
owns the address of the newly constructed array of type <code>T</code>
and size <code>size</code>.</p>
<p><b>Postconditions:</b>
<code>get() != 0 &amp;&amp; use_count() == 1</code>.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from
<code>A::allocate</code> or the constructor of <code>T</code>.</p>
<p><b>Notes:</b> This implementation allocates the memory required for
the returned <code>shared_ptr</code> and an array of type
<code>T</code> of size <code>size</code> in a single allocation. This
provides efficiency to equivalent to an intrusive smart array
pointer.</p>
<p>The prototypes shown above are used if your compiler supports r-value
references and variadic templates. They perfectly forward the
<code>args</code> parameters to the constructors of
<code>T</code> for each array element.</p>
<p>Otherwise, you can use the overloads which take only the array size
(and the allocator in case of <code>allocate_shared</code>) and do not
take any constructor arguments. These overloads invoke the default
constructor of <code>T</code> for each array element.</p>
</blockquote>
<pre>template&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared(Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, Args&amp;&amp;... args);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared(initializer_list&lt;T&gt; list);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, initializer_list&lt;T&gt; list);</pre>
<blockquote>
<p><b>Description:</b> These overloads initialize the array elements
from the initializer list.</p>
</blockquote>
<pre>template&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared(const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, const T (&amp;list)[N]);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename U, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; make_shared(size_t size, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, const T (&amp;list)[N]);</pre>
<blockquote>
<p><b>Description:</b> These overloads initialize inner array elements
from the initializer list.</p>
</blockquote>
<pre>template&lt;typename U, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; make_shared(const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, const T (&amp;list)[N]);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared(size_t size, T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, T&amp;&amp; value);</pre>
<blockquote>
<p><b>Description:</b> These overloads initialize array elements with
the given value.</p>
</blockquote>
<pre>template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared(T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, T&amp;&amp; value);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared_noinit(size_t size);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator, size_t size);</pre>
<blockquote>
<p><b>Description:</b> These overloads do not perform any value
initialization of elements.</p>
</blockquote>
<pre>template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared_noinit();
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<h2><a name="example">Example</a></h2>
<p>An example of each overload of make_shared for arrays:</p>
<blockquote>
<pre>boost::shared_ptr&lt;int[]&gt; a1 = boost::make_shared&lt;int[]&gt;(size);
boost::shared_ptr&lt;point[]&gt; a2 = boost::make_shared&lt;point[]&gt;(size, x, y);
boost::shared_ptr&lt;point[5]&gt; a3 = boost::make_shared&lt;point[5]&gt;(x, y);
boost::shared_ptr&lt;int[]&gt; a4 = boost::make_shared&lt;int[]&gt;({1, 2, 3});
boost::shared_ptr&lt;int[3]&gt; a5 = boost::make_shared&lt;int[3]&gt;({1, 2, 3});
boost::shared_ptr&lt;int[][3]&gt; a6 = boost::make_shared&lt;int[][3]&gt;(size, {1, 2, 3});
boost::shared_ptr&lt;int[5][3]&gt; a7 = boost::make_shared&lt;int[5][3]&gt;({1, 2, 3});
boost::shared_ptr&lt;point[]&gt; a8 = boost::make_shared&lt;point[]&gt;(size, {x, y});
boost::shared_ptr&lt;point[5]&gt; a9 = boost::make_shared&lt;point[5]&gt;({x, y});
boost::shared_ptr&lt;int[]&gt; a10 = boost::make_shared_noinit&lt;int[]&gt;(size);
boost::shared_ptr&lt;int[5]&gt; a11 = boost::make_shared_noinit&lt;int[5]&gt;();</pre>
</blockquote>
<h2><a name="history">History</a></h2>
<p>November 2012. Glen Fernandes contributed implementations of
make_shared and allocate_shared for arrays.</p>
<hr>
<p>$Date: 2012-10-30 10:12:25 -0800 (Tue, 30 Oct 2012) $</p>
<p><small>Copyright 2012 Glen Fernandes. Distributed under the Boost
Software License, Version 1.0. See accompanying file
<A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at
<A href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@@ -1,105 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>pointer_cast.hpp</title>
</head>
<body>
<h1><IMG height="86" alt="C++ Boost" src="../../boost.png" width="277" align="middle" border="0">Pointer
cast functions</h1>
<p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code>
<code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>)
provide a way to write generic pointer castings for raw pointers. The functions
are defined in <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A>.</CITE></p>
<P>There is test/example code in <CITE><A href="test/pointer_cast_test.cpp">pointer_cast_test.cpp</A></CITE>.</p>
<h2><a name="rationale">Rationale</a></h2>
<P>Boost smart pointers usually overload those functions to provide a mechanism to
emulate pointers casts. For example, <code>boost::shared_ptr&lt;...&gt;</code> implements
a static pointer cast this way:</P>
<pre>
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt; const &amp;r);
</pre>
<P>Pointer cast functions from <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A></CITE>
are overloads of <code>boost::static_pointer_cast</code>, <code>boost::dynamic_pointer_cast</code>,
<code>boost::reinterpret_pointer_cast</code> and <code>boost::const_pointer_cast</code>
for raw pointers. This way when developing pointer type independent classes,
for example, memory managers or shared memory compatible classes, the same code
can be used for raw and smart pointers.</p>
<H2><A name="synopsis">Synopsis</A></H2>
<BLOCKQUOTE>
<PRE>
namespace boost {
template&lt;class T, class U&gt;
inline T* static_pointer_cast(U *ptr)
{ return static_cast&lt;T*&gt;(ptr); }
template&lt;class T, class U&gt;
inline T* dynamic_pointer_cast(U *ptr)
{ return dynamic_cast&lt;T*&gt;(ptr); }
template&lt;class T, class U&gt;
inline T* const_pointer_cast(U *ptr)
{ return const_cast&lt;T*&gt;(ptr); }
template&lt;class T, class U&gt;
inline T* reinterpret_pointer_cast(U *ptr)
{ return reinterpret_cast&lt;T*&gt;(ptr); }
} // namespace boost
</PRE>
</BLOCKQUOTE>
<P>As you can see from the above synopsis, the pointer cast functions are just
wrappers around standard C++ cast operators.</P>
<H2><A name="example">Example</A></H2>
<BLOCKQUOTE>
<PRE>
#include &lt;boost/pointer_cast.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
class base
{
public:
virtual ~base()
{
}
};
class derived: public base
{
};
template &lt;class BasePtr&gt;
void check_if_it_is_derived(const BasePtr &amp;ptr)
{
assert(boost::dynamic_pointer_cast&lt;derived&gt;(ptr) != 0);
}
int main()
{
<I>// Create a raw and a shared_ptr</I>
base *ptr = new derived;
boost::shared_ptr&lt;base&gt; sptr(new derived);
<I>// Check that base pointer points actually to derived class</I>
check_if_it_is_derived(ptr);
check_if_it_is_derived(sptr);
// <EM>Ok!</EM>
delete ptr;
return 0;
}</PRE>
</BLOCKQUOTE>
<P>The example demonstrates how the generic pointer casts help us create pointer
independent code.</P>
<hr>
<p>Revised: $Date$</p>
<p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to
the Boost Software License, Version 1.0. (See accompanying file <A href="../../LICENSE_1_0.txt">
LICENSE_1_0.txt</A> or a copy at &lt;<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>&gt;.)</p>
</body>
</html>

View File

@@ -1,108 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>pointer_to_other.hpp</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Header
<a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a></h1>
<p>
The pointer to other utility provides a way, given a source pointer type,
to obtain a pointer of the same type to another pointee type. The utility is
defined in <cite><a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a>.</cite></p>
<p>There is test/example code in <cite><a href="test/pointer_to_other_test.cpp">pointer_to_other_test.cpp</a></cite>.</p>
<h2><a name="contents">Contents</a></h2>
<ul>
<li>
<a href="#rationale">Rationale</a>
<li>
<a href="#synopsis">Synopsis</a>
<li>
<a href="#example">Example</a></li>
</ul>
<h2><a name="rationale">Rationale</a></h2>
<p>When building pointer independent classes, like memory managers, allocators, or
containers, there is often a need to define pointers generically, so that if a
template parameter represents a pointer (for example, a raw or smart pointer to
an int), we can define another pointer of the same type to another pointee (a
raw or smart pointer to a float.)</p>
<pre>template &lt;class IntPtr&gt;
class FloatPointerHolder
{
<em>// Let's define a pointer to a float</em>
typedef typename boost::pointer_to_other
&lt;IntPtr, float&gt;::type float_ptr_t;
float_ptr_t float_ptr;
};</pre>
<h2><a name="synopsis">Synopsis</a></h2>
<pre>
namespace boost {
template&lt;class T, class U&gt;
struct pointer_to_other;
template&lt;class T, class U, template &lt;class&gt; class Sp&gt;
struct pointer_to_other&lt; Sp&lt;T&gt;, U &gt;
{
typedef Sp&lt;U&gt; type;
};
template&lt;class T, class T2, class U,
template &lt;class, class&gt; class Sp&gt;
struct pointer_to_other&lt; Sp&lt;T, T2&gt;, U &gt;
{
typedef Sp&lt;U, T2&gt; type;
};
template&lt;class T, class T2, class T3, class U,
template &lt;class, class, class&gt; class Sp&gt;
struct pointer_to_other&lt; Sp&lt;T, T2, T3&gt;, U &gt;
{
typedef Sp&lt;U, T2, T3&gt; type;
};
template&lt;class T, class U&gt;
struct pointer_to_other&lt; T*, U &gt;
{
typedef U* type;
};
} <em>// namespace boost</em></pre>
<p>If these definitions are not correct for a specific smart pointer, we can define
a specialization of pointer_to_other.</p>
<h2><a name="example">Example</a></h2>
<pre><em>// Let's define a memory allocator that can
// work with raw and smart pointers</em>
#include &lt;boost/pointer_to_other.hpp&gt;
template &lt;class VoidPtr&gt;
class memory_allocator
{<em>
// Predefine a memory_block </em>
struct block;<em>
// Define a pointer to a memory_block from a void pointer
// If VoidPtr is void *, block_ptr_t is block*
// If VoidPtr is smart_ptr&lt;void&gt;, block_ptr_t is smart_ptr&lt;block&gt;</em>
typedef typename boost::pointer_to_other
&lt;VoidPtr, block&gt;::type block_ptr_t;
struct block
{
std::size_t size;
block_ptr_t next_block;
};
block_ptr_t free_blocks;
};</pre>
<p>As we can see, using pointer_to_other we can create pointer independent code.</p>
<hr>
<p>Last revised: $Date$</p>
<p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification,
and distribution are subject to the Boost Software License, Version 1.0.<br>
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a
copy at &lt; <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</small></p>
</body>
</html>

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>scoped_array class template</h1>
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"><a name="scoped_array">scoped_array</a>
class template</h1>
<p>The <b>scoped_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b>
expression.) The array pointed to is guaranteed to be deleted, either on
@@ -14,9 +14,10 @@
<p>The <b>scoped_array</b> template is a simple solution for simple needs. It
supplies a basic "resource acquisition is initialization" facility, without
shared-ownership or transfer-of-ownership semantics. Both its name and
enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
noncopyable</a>) signal its intent to retain ownership solely within the
current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>,
enforcement of semantics (by being
<a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>) signal its intent to retain ownership solely within the
current scope. Because it is
<a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>,
it is safer than <b>shared_array</b> for pointers which should not be copied.</p>
<p>Because <b>scoped_array</b> is so simple, in its usual implementation every
operation is as fast as a built-in array pointer and it has no more space
@@ -47,8 +48,6 @@
T &amp; <a href="#operator[]">operator[]</a>(std::ptrdiff_t i) const; // never throws
T * <a href="#get">get</a>() const; // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
void <a href="#swap">swap</a>(scoped_array &amp; b); // never throws
};
@@ -91,10 +90,6 @@
<pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_array &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
@@ -106,11 +101,11 @@
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
Provided as an aid to generic programming.</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan-->
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 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>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan-->09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. 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>
</html>

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>scoped_ptr class template</h1>
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"><a name="scoped_ptr">scoped_ptr</a>
class template</h1>
<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated
object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.)
The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>,
@@ -48,8 +48,6 @@
T * <a href="#indirection">operator-&gt;</a>() const; // never throws
T * <a href="#get">get</a>() const; // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
void <a href="#swap">swap</a>(scoped_ptr &amp; b); // never throws
};
@@ -92,10 +90,6 @@
<pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
@@ -156,8 +150,8 @@ Buckle my shoe</pre>
<p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called
pimpl) idiom which avoids exposing the body (implementation) in the header
file.</p>
<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a>
sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a> sample
program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
which uses a <b>scoped_ptr&lt;&gt;</b> to an incomplete type to hide the
implementation. The instantiation of member functions which require a complete
type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a>
@@ -171,11 +165,12 @@ Buckle my shoe</pre>
given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership
is required. (supplied by Dave Abrahams)</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 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>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002 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.</p>
</body>
</html>

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>shared_array class template</h1>
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86">shared_array
class template</h1>
<p>The <b>shared_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
@@ -47,14 +47,12 @@
void <a href="#reset">reset</a>(T * p = 0);
template&lt;class D&gt; void <a href="#reset">reset</a>(T * p, D d);
T &amp; <a href="#indexing">operator[]</a>(std::ptrdiff_t i) const; // never throws
T &amp; <a href="#indexing">operator[]</a>(std::ptrdiff_t i) const() const; // never throws
T * <a href="#get">get</a>() const; // never throws
bool <a href="#unique">unique</a>() const; // never throws
long <a href="#use_count">use_count</a>() const; // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
void <a href="#swap">swap</a>(shared_array&lt;T&gt; &amp; b); // never throws
};
@@ -141,10 +139,6 @@
implementations of <b>shared_array</b> that do not use an explicit reference
count, it might be removed from some future version. Thus it should be used for
debugging purposes only, and not production code.</p>
<h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(shared_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
@@ -177,9 +171,10 @@ template&lt;class T&gt;
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 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>
<p>Copyright 1999 Greg Colvin and Beman Dawes. 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>

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>Smart Pointers</h1>
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86">Smart
Pointers</h1>
<p><a href="#Introduction">Introduction</a><br>
<a href="#common_requirements">Common Requirements</a><br>
<a href="#Exception_Safety">Exception Safety</a><br>
@@ -14,15 +14,15 @@
<a href="#History">History and Acknowledgements</a><br>
<a href="#References">References</a></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>Smart pointers are objects which store pointers to dynamically allocated (heap)
objects. They behave much like built-in C++ pointers except that they
automatically delete the object pointed to at the appropriate time. Smart
pointers are particularly useful in the face of exceptions as they ensure
proper destruction of dynamically allocated objects. They can also be used to
<p>Smart pointers are objects which store pointers to dynamically allocated (heap)
objects. They behave much like built-in C++ pointers except that they
automatically delete the object pointed to at the appropriate time. Smart
pointers are particularly useful in the face of exceptions as they ensure
proper destruction of dynamically allocated objects. They can also be used to
keep track of dynamically allocated objects shared by multiple owners.</p>
<p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
<p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
responsible for deletion of the object when it is no longer needed.</p>
<p>The smart pointer library provides six smart pointer class templates:</p>
<p>The smart pointer library provides five smart pointer class templates:</p>
<div align="left">
<table border="1" cellpadding="4" cellspacing="0">
<tr>
@@ -38,7 +38,7 @@
<tr>
<td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td>
<td><a href="../../boost/shared_ptr.hpp">&lt;boost/shared_ptr.hpp&gt;</a></td>
<td>Object ownership shared among multiple pointers.</td>
<td>Object ownership shared among multiple pointers</td>
</tr>
<tr>
<td><a href="shared_array.htm"><b>shared_array</b></a></td>
@@ -58,150 +58,129 @@
</table>
</div>
<p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p>
<p>They are examples of the "resource acquisition is initialization" idiom
described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
<p>They are examples of the "resource acquisition is initialization" idiom
described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
Section 14.4, Resource Management.</p>
<p>Additionally, the smart pointer library provides efficient factory functions
for creating <code>shared_ptr</code> objects:</p>
<div align="left">
<table border="1" cellpadding="4" cellspacing="0">
<tr>
<td><a href="make_shared.html"><b>make_shared and allocate_shared</b></a></td>
<td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td>
<td>Efficient creation of <code>shared_ptr</code> objects.</td>
</tr>
<tr>
<td><a href="make_shared_array.html"><b>make_shared and allocate_shared for arrays</b></a></td>
<td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td>
<td>Efficient creation of <code>shared_ptr</code> arrays.</td>
</tr>
</table>
</div>
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
provided to verify correct operation.</p>
<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
the Boost smart pointer library describes some of the changes since earlier
<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
the Boost smart pointer library describes some of the changes since earlier
versions of the smart pointer implementation.</p>
<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
to those curious about performance issues.</p>
<P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists
<P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists
some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P>
<h2><a name="common_requirements">Common Requirements</a></h2>
<p>These smart pointer class templates have a template parameter, <b>T</b>, which
specifies the type of the object pointed to by the smart pointer. The behavior
<p>These smart pointer class templates have a template parameter, <b>T</b>, which
specifies the type of the object pointed to by the smart pointer. The behavior
of the smart pointer templates is undefined if the destructor or <b>operator delete</b>
for objects of type <b>T</b> throw exceptions.</p>
<p><b>T</b> may be an incomplete type at the point of smart pointer declaration.
Unless otherwise specified, it is required that <b>T</b> be a complete type at
points of smart pointer instantiation. Implementations are required to diagnose
(treat as an error) all violations of this requirement, including deletion of
<p><b>T</b> may be an incomplete type at the point of smart pointer declaration.
Unless otherwise specified, it is required that <b>T</b> be a complete type at
points of smart pointer instantiation. Implementations are required to diagnose
(treat as an error) all violations of this requirement, including deletion of
an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete">
<b>checked_delete</b></a> function template.</p>
<P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
<P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
its member functions do not require <STRONG>T</STRONG> to be a complete type.</P>
<h3>Rationale</h3>
<p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow
handle-body (also called pimpl) and similar idioms. In these idioms a smart
pointer may appear in translation units where <b>T</b> is an incomplete type.
This separates interface from implementation and hides implementation from
translation units which merely use the interface. Examples described in the
documentation for specific smart pointers illustrate use of smart pointers in
<p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow
handle-body (also called pimpl) and similar idioms. In these idioms a smart
pointer may appear in translation units where <b>T</b> is an incomplete type.
This separates interface from implementation and hides implementation from
translation units which merely use the interface. Examples described in the
documentation for specific smart pointers illustrate use of smart pointers in
these idioms.</p>
<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
destruction time, but <b>shared_ptr</b> does not.</p>
<h2><a name="Exception_Safety">Exception Safety</a></h2>
<p>Several functions in these smart pointer classes are specified as having "no
effect" or "no effect except such-and-such" if an exception is thrown. This
means that when an exception is thrown by an object of one of these classes,
the entire program state remains the same as it was prior to the function call
which resulted in the exception being thrown. This amounts to a guarantee that
there are no detectable side effects. Other functions never throw exceptions.
The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
and that is thrown only by functions which are explicitly documented as
<p>Several functions in these smart pointer classes are specified as having "no
effect" or "no effect except such-and-such" if an exception is thrown. This
means that when an exception is thrown by an object of one of these classes,
the entire program state remains the same as it was prior to the function call
which resulted in the exception being thrown. This amounts to a guarantee that
there are no detectable side effects. Other functions never throw exceptions.
The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
and that is thrown only by functions which are explicitly documented as
possibly throwing <b>std::bad_alloc</b>.</p>
<h2><a name="Exception-specifications">Exception-specifications</a></h2>
<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
<p>Exception-specifications are not used; see <a href="../../more/lib_guide.htm#Exception-specification">
exception-specification rationale</a>.</p>
<p>All the smart pointer templates contain member functions which can never throw
exceptions, because they neither throw exceptions themselves nor call other
<p>All the smart pointer templates contain member functions which can never throw
exceptions, because they neither throw exceptions themselves nor call other
functions which may throw exceptions. These members are indicated by a comment: <code>
// never throws</code>.
</p>
<p>Functions which destroy objects of the pointed to type are prohibited from
<p>Functions which destroy objects of the pointed to type are prohibited from
throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
<h2><a name="History">History</a> and Acknowledgements</h2>
<p>November 2012. Glen Fernandes provided implementations of <b>make_shared</b>
and <b>allocate_shared</b> for arrays. They achieve a single allocation for an
array that can be initialized with constructor arguments or initializer lists
as well as overloads for default initialization and no value initialization.
See the <a href="make_shared_array.html">make_shared and allocate_shared for
arrays</a> page for more information.</p>
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
See the <a href="compatibility.htm">compatibility</a> page for a summary of the
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
See the <a href="compatibility.htm">compatibility</a> page for a summary of the
changes.</p>
<p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
<p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
others.</p>
<p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b>
and <b>std::less</b> specializations for shared types.</p>
<p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p>
<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
number of suggestions resulting in numerous improvements.</p>
<p>October 1998. Beman Dawes proposed reviving the original semantics under the
names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt
Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K&uuml;hl,
Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new
class names were finalized, it was decided that there was no need to exactly
follow the <b>std::auto_ptr</b> interface, and various function signatures and
<p>October 1998. Beman Dawes proposed reviving the original semantics under the
names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt
Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K<EFBFBD>hl,
Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new
class names were finalized, it was decided that there was no need to exactly
follow the <b>std::auto_ptr</b> interface, and various function signatures and
semantics were finalized.</p>
<p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
The implementation questions revolved around the reference count which must be
kept, either attached to the pointed to object, or detached elsewhere. Each of
<p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
The implementation questions revolved around the reference count which must be
kept, either attached to the pointed to object, or detached elsewhere. Each of
those variants have themselves two major variants:
<ul>
<li>
Direct detached: the shared_ptr contains a pointer to the object, and a pointer
Direct detached: the shared_ptr contains a pointer to the object, and a pointer
to the count.
<li>
Indirect detached: the shared_ptr contains a pointer to a helper object, which
Indirect detached: the shared_ptr contains a pointer to a helper object, which
in turn contains a pointer to the object and the count.
<li>
Embedded attached: the count is a member of the object pointed to.
<li>
Placement attached: the count is attached via operator new manipulations.</li>
</ul>
<p>Each implementation technique has advantages and disadvantages. We went so far
as to run various timings of the direct and indirect approaches, and found that
at least on Intel Pentium chips there was very little measurable difference.
Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
K&uuml;hl suggested an elegant partial template specialization technique to allow
users to choose which implementation they preferred, and that was also
<p>Each implementation technique has advantages and disadvantages. We went so far
as to run various timings of the direct and indirect approaches, and found that
at least on Intel Pentium chips there was very little measurable difference.
Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
K<EFBFBD>hl suggested an elegant partial template specialization technique to allow
users to choose which implementation they preferred, and that was also
experimented with.</p>
<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
users", and in the end we choose to supply only the direct implementation.</p>
<p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b>
and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b>
and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few
cases where the Library Working Group's recommendations were not followed by
the full committee, <b>counted_ptr</b> was rejected and surprising
and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few
cases where the Library Working Group's recommendations were not followed by
the full committee, <b>counted_ptr</b> was rejected and surprising
transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
<h2><a name="References">References</a></h2>
<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
July, 1994.</p>
<p>[<a name="E&amp;D-94">E&amp;D-94</a>] John R. Ellis &amp; David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings,
February, 1994. This paper includes an extensive discussion of weak pointers
Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings,
February, 1994. This paper includes an extensive discussion of weak pointers
and an extensive bibliography.</p>
<hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. 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>Copyright 1999 Greg Colvin and Beman Dawes. 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>

Some files were not shown because too many files have changed in this diff Show More