Compare commits

...

91 Commits

Author SHA1 Message Date
c839ee7e42 This commit was manufactured by cvs2svn to create tag
'Version_1_33_1_beta'.

[SVN r31604]
2005-11-08 23:18:41 +00:00
b179f44d79 Switched to 'int' since 'long' is 64 bits on PPC64
[SVN r30651]
2005-08-24 17:15:49 +00:00
dff0529ad5 Removed explicit register use (thanks to Howard Hinnant)
[SVN r30585]
2005-08-15 19:44:15 +00:00
72c5cc395a fixed broken links
[SVN r30431]
2005-08-03 21:42:39 +00:00
9945f4e158 This commit was manufactured by cvs2svn to create branch 'RC_1_33_0'.
[SVN r30300]
2005-07-28 18:22:24 +00:00
afc17037de Another minor documentation fix.
[SVN r30224]
2005-07-22 23:40:53 +00:00
0cee41d47e Minor documentation fix.
[SVN r30190]
2005-07-21 00:51:38 +00:00
eb3d3464db operator< documenation fix.
[SVN r30166]
2005-07-18 20:33:59 +00:00
8d2aeea3a8 Moved warning 8027 suppression above the #includes
[SVN r29852]
2005-06-30 21:49:40 +00:00
675d09723a Lock-free implementation documented, minor changes to align with TR1
[SVN r29536]
2005-06-12 12:58:17 +00:00
24c23b8064 disabled asm implementation for ICC/IA64
[SVN r29166]
2005-05-24 12:11:35 +00:00
880c2e1062 Detabified.
[SVN r29039]
2005-05-18 20:10:01 +00:00
357f57d147 Added a weak_ptr timing test.
[SVN r28483]
2005-04-26 11:08:28 +00:00
8bacee46eb Add x86 assembly implementation for use with CodeWarrior. Commented out initially until we can get more widespread testing for verification of performance improvements (if any).
[SVN r28422]
2005-04-22 16:36:38 +00:00
4e4ec29fc9 Added an implementation of sp_counted_base for g++/ia64.
[SVN r28325]
2005-04-19 17:43:48 +00:00
df1d8b27df Make assembly functions inline to prevent multiple definitions. Required to change from function level assembly to regular functions with statement level assembly.
[SVN r28133]
2005-04-11 15:59:44 +00:00
76722e125f Clear reservation for 970 (thanks to Miro Jurisic and Philip Koch)
[SVN r28060]
2005-04-08 10:39:28 +00:00
d24f6d3b97 Remove hardcoded ebx
[SVN r28017]
2005-04-06 14:12:40 +00:00
6ab6b66601 One more long -> int fix
[SVN r28016]
2005-04-06 13:40:34 +00:00
559056c856 x86-64 fixes: long -> int, lea -> mov+inc
[SVN r28015]
2005-04-06 13:34:41 +00:00
13c128f98f Enabled PPC versions
[SVN r28007]
2005-04-06 08:15:48 +00:00
3ebc9b8f0b Remove extra argument to atomic_dcrement.
[SVN r27994]
2005-04-06 00:32:09 +00:00
361a7c3fd0 PowerPC dispatch added, disabled for now.
[SVN r27988]
2005-04-05 20:39:56 +00:00
faa675ad6a PowerPC implementations added.
[SVN r27986]
2005-04-05 20:29:15 +00:00
319836fe78 Constraints fixed (again), volatile/memory clobber removed from conditional_inc
[SVN r27983]
2005-04-05 16:04:36 +00:00
d0656015ad Fixed 'eax' to '%eax' in clobber; enabled gcc/x86 version
[SVN r27965]
2005-04-04 22:43:03 +00:00
f1a9148a43 Constraints fixed for g++ 3.4, atomic_increment added
[SVN r27958]
2005-04-04 19:36:18 +00:00
1942b64751 weak_ptr_mt_test.cpp added.
[SVN r27938]
2005-04-02 19:35:58 +00:00
a0eb5daf75 Mark eax as earlyclobber
[SVN r27937]
2005-04-02 18:56:38 +00:00
6046a099ba Added an implementation of sp_counted_base for g++/x86
[SVN r27933]
2005-04-02 17:14:26 +00:00
e0ee037e2d Spinlocks removed.
[SVN r27932]
2005-04-02 13:12:28 +00:00
13657c8bda lw_mutex_test added.
[SVN r27931]
2005-04-02 12:51:17 +00:00
52587aaa05 Fixed shared_ptr_delete_fail failure on g++ 3.3 and below
[SVN r27930]
2005-04-02 12:00:14 +00:00
0669d41076 Atomics are in namespace __gnu_cxx for g++ 3.4+
[SVN r27929]
2005-04-02 11:37:53 +00:00
8f2beee8e9 Link fixed.
[SVN r27906]
2005-04-01 19:33:00 +00:00
3adfc7842c Kill *_linux variants of atomic_count and lightweight_mutex.
[SVN r27889]
2005-03-30 22:52:54 +00:00
613e684b30 shared_ptr_delete_fail.cpp added (reported by Dan Bikel)
[SVN r27888]
2005-03-30 22:06:25 +00:00
bfc0225cda Switched to atomic_count
[SVN r27811]
2005-03-24 21:55:24 +00:00
a67e505cf5 Made use of detail/interlocked.hpp
[SVN r27810]
2005-03-24 21:29:29 +00:00
adec862262 atomic_count_test.cpp added.
[SVN r27746]
2005-03-20 15:40:30 +00:00
c6bf857f8b Made the pthread mutex mutable
[SVN r27740]
2005-03-18 21:27:22 +00:00
14024e2598 Add a comment thanking Ben Hutchings for the #w+(#s!=0) formulation
[SVN r27735]
2005-03-18 13:04:43 +00:00
34953d8a45 Split sp_counted_base into no threads (nt), win32 lock-free (w32) and pthreads (pt)
[SVN r27729]
2005-03-18 01:27:11 +00:00
09a0ba8c75 sp_counted_impl_p added for the pointer constructor
[SVN r27727]
2005-03-17 23:30:47 +00:00
b0eb65b433 Refactored sp_counted_impl.hpp out of shared_count.hpp
[SVN r27726]
2005-03-17 23:05:26 +00:00
c830315dff Refactored shared_count.hpp into bad_weak_ptr.hpp, sp_counted_base.hpp
[SVN r27725]
2005-03-17 22:45:11 +00:00
b07447aa6e BCB 6.4 still needs option -pc (reported by Pavel Vozenilek)
[SVN r27672]
2005-03-15 16:02:01 +00:00
42a739b357 Fixed nonportable elision assumption.
[SVN r27093]
2005-02-04 16:39:44 +00:00
7d59d29ad1 HP aCC fix for get_deleter (Jaroslav Gresula)
[SVN r27092]
2005-02-04 16:28:50 +00:00
5616a1a872 Added note on BOOST_MEM_FN_ENABLE_STDCALL.
[SVN r26687]
2005-01-13 13:45:59 +00:00
e5c1e12a66 merge RC_1_32_0 fixes
[SVN r26333]
2004-11-28 04:44:21 +00:00
8f317492ee Outdated comment removed (Jonathan Wakely)
[SVN r26272]
2004-11-22 12:32:35 +00:00
c81be1e2e7 c++boost.gif -> boost.png replacement
[SVN r25573]
2004-10-05 15:45:52 +00:00
1bc58ea861 Updated to use the BSL (using permissions supplied in more/blanket-permission.txt)
[SVN r24804]
2004-08-29 10:29:46 +00:00
27be736b8f Fixed sp_enable_shared_from_this to not use void cv * since this breaks function types.
[SVN r24718]
2004-08-24 16:27:31 +00:00
ef51f6a1de License update
[SVN r24598]
2004-08-19 15:23:47 +00:00
6b00a55542 License updates
[SVN r24597]
2004-08-19 15:19:17 +00:00
858cefbfe8 Removed boost.org copyright assignments, and reverted to orginal author (as based on cvs history).
[SVN r24402]
2004-08-11 10:59:33 +00:00
c7abff0099 Updated Beman Dawes' licence statement to use the new prefered form of words.
[SVN r24370]
2004-08-10 10:34:20 +00:00
cb6cb636f7 Converted to Boost Software License, Version 1.0
[SVN r24055]
2004-07-26 00:32:12 +00:00
366d2666d4 Licence update
[SVN r24031]
2004-07-25 12:01:00 +00:00
9c67a59d43 Fixed lwm_gcc, had the same bug as atomic_count_gcc (Tyson Whitehead)
[SVN r23367]
2004-07-06 10:52:06 +00:00
7361e476b8 Fixed operator--
[SVN r23210]
2004-06-27 15:40:29 +00:00
e1bd18f6a6 Made value_ mutable to enable operator long() const to compile
[SVN r23208]
2004-06-27 15:09:46 +00:00
1346982b80 Fix a typo
[SVN r23077]
2004-06-10 12:31:20 +00:00
c48f05dcb4 enable_shared_from_this is now const-tolerant.
[SVN r22298]
2004-02-16 18:50:07 +00:00
53cc52127b Self-assignment optimization
[SVN r22233]
2004-02-10 23:17:12 +00:00
7fb399b3bb index.htm renamed index.html
[SVN r21231]
2003-12-11 23:31:15 +00:00
93d69af60a _MSC_VER use clarified.
[SVN r20992]
2003-11-28 15:35:21 +00:00
09c8685181 Fixed a VC7 'regression' (pointers to volatile cannot be deleted)
[SVN r20977]
2003-11-27 16:58:23 +00:00
15d6b2aace CWPro8 workaround
[SVN r20323]
2003-10-09 14:14:26 +00:00
feff6e40ea Use conforming is_class for EDG compilers
Make is_enum work for class types which are convertible to anything at
all (on many compilers).

smart_ptr library workarounds for __MWERKS__ (must use member function
pointer for unspecified_bool_type).


[SVN r20244]
2003-10-02 17:49:06 +00:00
26a93f224e Changed index.htm to redirect to smart_ptr.htm
[SVN r20239]
2003-10-01 11:13:04 +00:00
96f572b19b Switched unspecified_bool_type to data member pointer.
[SVN r20238]
2003-10-01 11:12:15 +00:00
d6c4633e89 Add V2 Jamfile
[SVN r20223]
2003-09-30 07:42:34 +00:00
106a6d58d4 Change license message to reference Boost Software License
[SVN r20038]
2003-09-12 17:09:29 +00:00
debd953d8f Use the import rule
[SVN r19968]
2003-09-08 17:38:49 +00:00
f2c5439644 'volatile' fixes.
[SVN r19961]
2003-09-08 12:26:02 +00:00
b4ec0e90fb Switched weak_count_ from #shared+#weak to #weak+(#shared != 0); thanks to Alexander Terekhov and Ben Hutchings
[SVN r19246]
2003-07-21 14:17:03 +00:00
2d4eb92401 get_deleter fix for EDG 2.38
[SVN r19148]
2003-07-16 11:54:49 +00:00
192970b3b8 const_pointer_cast added.
[SVN r19147]
2003-07-16 11:51:12 +00:00
7c36a640ae add_ref split to add_ref_copy and add_ref_lock to eliminate the redundant use_count_ == 0 check.
[SVN r19126]
2003-07-15 12:18:40 +00:00
794de98cd1 #include <boost/config.hpp> added.
[SVN r19065]
2003-07-11 17:03:56 +00:00
dcdbaf1e57 A binary compatible 'null' lightweight_mutex for Win32 added.
[SVN r18916]
2003-07-02 11:54:40 +00:00
6dbec7621d Detect the VC6 STL, not VC6 itself (for Intel)
[SVN r18837]
2003-06-18 16:03:09 +00:00
889cb6bee6 -Wundef fixes.
[SVN r18788]
2003-06-12 17:09:24 +00:00
11cddbbb45 Minor fix, scoped_ptr in the intro should've been shared_ptr.
[SVN r18745]
2003-06-09 18:25:41 +00:00
77c629b6e4 smart_ptr.hpp now includes all smart pointer headers for convenience.
[SVN r18588]
2003-05-28 13:51:35 +00:00
d091ee85c0 Turns out Sun CC doesn't like operator int().
[SVN r18512]
2003-05-23 13:46:07 +00:00
bc00d5fa1a Fixed bool conversions for Sun 5.3
[SVN r18419]
2003-05-16 12:11:17 +00:00
e760759414 Fixed a copy/assignment issue.
[SVN r18122]
2003-03-28 12:27:55 +00:00
77 changed files with 2801 additions and 1254 deletions

View File

@ -9,7 +9,7 @@
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Smart
<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

View File

@ -8,7 +8,7 @@
<table border="0" width="100%">
<tr>
<td width="277">
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
</td>
<td align="middle">
<h1>enable_shared_from_this.hpp</h1>

View File

@ -1,12 +1,11 @@
// Boost scoped_ptr_example implementation file -----------------------------//
// (C) Copyright Beman Dawes 2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// See http://www.boost.org/libs/smart_ptr for documentation.
#include "scoped_ptr_example.hpp"
#include <iostream>

View File

@ -1,12 +1,11 @@
// Boost scoped_ptr_example header file ------------------------------------//
// (C) Copyright Beman Dawes 2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// See http://www.boost.org/libs/smart_ptr for documentation.
#include <boost/utility.hpp>
#include <boost/scoped_ptr.hpp>

View File

@ -1,12 +1,11 @@
// Boost scoped_ptr_example_test main program -------------------------------//
// (C) Copyright Beman Dawes 2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// See http://www.boost.org/libs/smart_ptr for documentation.
#include "scoped_ptr_example.hpp"

View File

@ -1,12 +1,11 @@
// Boost shared_ptr_example.cpp --------------------------------------------//
// (C) Copyright Beman Dawes 2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// See http://www.boost.org/libs/smart_ptr for documentation.
// Revision History
// 21 May 01 Initial complete version (Beman Dawes)

View File

@ -1,12 +1,11 @@
// Boost shared_ptr_example2 implementation file -----------------------------//
// (C) Copyright Beman Dawes 2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// See http://www.boost.org/libs/smart_ptr for documentation.
#include "shared_ptr_example2.hpp"
#include <iostream>

View File

@ -1,12 +1,11 @@
// Boost shared_ptr_example2 header file -----------------------------------//
// (C) Copyright Beman Dawes 2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// See http://www.boost.org/libs/smart_ptr for documentation.
#include <boost/shared_ptr.hpp>

View File

@ -1,12 +1,11 @@
// Boost shared_ptr_example2_test main program ------------------------------//
// (C) Copyright Beman Dawes 2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// See http://www.boost.org/libs/smart_ptr for documentation.
#include "shared_ptr_example2.hpp"

View File

@ -1,8 +1,10 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
@ -10,10 +12,9 @@
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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;
//
@ -72,9 +73,6 @@
// are called driven by smart_ptr interface...
//
// Note: atomic_count_linux.hpp has been disabled by default; see the
// comments inside for more info.
#include <boost/config.hpp>
#ifndef BOOST_HAS_THREADS
@ -91,13 +89,11 @@ typedef long atomic_count;
}
#elif defined(BOOST_USE_ASM_ATOMIC_H)
# include <boost/detail/atomic_count_linux.hpp>
#elif defined(BOOST_AC_USE_PTHREADS)
# include <boost/detail/atomic_count_pthreads.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/atomic_count_win32.hpp>
#elif defined(__GLIBCPP__)
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# include <boost/detail/atomic_count_gcc.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_AC_USE_PTHREADS

View File

@ -10,11 +10,11 @@
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2002 Lars Gullik Bj<42>nnes <larsbj@lyx.org>
// Copyright 2003-2005 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <bits/atomicity.h>
@ -25,6 +25,13 @@ namespace boost
namespace detail
{
#if defined(__GLIBCXX__) // g++ 3.4+
using __gnu_cxx::__atomic_add;
using __gnu_cxx::__exchange_and_add;
#endif
class atomic_count
{
public:
@ -38,7 +45,7 @@ public:
long operator--()
{
return !__exchange_and_add(&value_, -1);
return __exchange_and_add(&value_, -1) - 1;
}
operator long() const
@ -51,7 +58,7 @@ private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
_Atomic_word value_;
mutable _Atomic_word value_;
};
} // namespace detail

View File

@ -1,70 +0,0 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
//
// boost/detail/atomic_count_linux.hpp
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//
// This implementation uses <asm/atomic.h>. This is a kernel header;
// using kernel headers in a user program may cause a number of problems,
// and not all flavors of Linux provide the atomic instructions.
//
// This file is only provided because the performance of this implementation
// is significantly higher than the pthreads version. Use at your own risk
// (by defining BOOST_USE_ASM_ATOMIC_H.)
//
#include <asm/atomic.h>
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count(long v)
{
atomic_t init = ATOMIC_INIT(v);
value_ = init;
}
void operator++()
{
atomic_inc(&value_);
}
long operator--()
{
return !atomic_dec_and_test(&value_);
}
operator long() const
{
return atomic_read(&value_);
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
atomic_t value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED

View File

@ -6,10 +6,9 @@
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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>

View File

@ -1,24 +1,23 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/atomic_count_win32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov
// Copyright (c) 2001-2005 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifdef BOOST_USE_WINDOWS_H
# include <windows.h>
#endif
#include <boost/detail/interlocked.hpp>
namespace boost
{
@ -26,67 +25,35 @@ namespace boost
namespace detail
{
#ifndef BOOST_USE_WINDOWS_H
#ifdef _WIN64
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
extern "C" long_type __cdecl _InterlockedIncrement(long volatile *);
extern "C" long_type __cdecl _InterlockedDecrement(long volatile *);
#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)
inline long InterlockedIncrement(long volatile * lp)
{
return _InterlockedIncrement(lp);
}
inline long InterlockedDecrement(long volatile* lp)
{
return _InterlockedDecrement(lp);
}
#else // _WIN64
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile *);
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile *);
#endif // _WIN64
#endif // #ifndef BOOST_USE_WINDOWS_H
class atomic_count
{
public:
explicit atomic_count(long v): value_(v)
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
// Some older <windows.h> versions do not accept volatile
return InterlockedIncrement(const_cast<long*>(&value_));
return BOOST_INTERLOCKED_INCREMENT( &value_ );
}
long operator--()
{
return InterlockedDecrement(const_cast<long*>(&value_));
return BOOST_INTERLOCKED_DECREMENT( &value_ );
}
operator long() const
{
return value_;
return static_cast<long const volatile &>( value_ );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
atomic_count( atomic_count const & );
atomic_count & operator=( atomic_count const & );
volatile long value_;
long value_;
};
} // namespace detail

View File

@ -0,0 +1,59 @@
#ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED
#define BOOST_BAD_WEAK_PTR_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/bad_weak_ptr.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <exception>
#ifdef __BORLANDC__
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
#endif
namespace boost
{
// The standard library that comes with Borland C++ 5.5.1, 5.6.4
// defines std::exception and its members as having C calling
// convention (-pc). When the definition of bad_weak_ptr
// is compiled with -ps, the compiler issues an error.
// Hence, the temporary #pragma option -pc below.
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
# pragma option push -pc
#endif
class bad_weak_ptr: public std::exception
{
public:
virtual char const * what() const throw()
{
return "boost::bad_weak_ptr";
}
};
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
# pragma option pop
#endif
} // namespace boost
#ifdef __BORLANDC__
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
#endif
#endif // #ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED

View File

@ -1,85 +1,38 @@
#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
// 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 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// typedef <unspecified> boost::detail::lightweight_mutex;
//
// boost::detail::lightweight_mutex meets a subset of the Mutex concept
// requirements: http://www.boost.org/libs/thread/doc/mutex_concept.html#Mutex
// boost::detail::lightweight_mutex is a header-only implementation of
// a subset of the Mutex concept requirements:
//
// * Used by the smart pointer library
// * Performance oriented
// * Header-only implementation
// * Small memory footprint
// * Not a general purpose mutex, use boost::mutex, CRITICAL_SECTION or
// pthread_mutex instead.
// * Never spin in a tight lock/do-something/unlock loop, since
// lightweight_mutex does not guarantee fairness.
// * Never keep a lightweight_mutex locked for long periods.
// http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
//
// The current implementation can use a pthread_mutex, a CRITICAL_SECTION,
// or a platform-specific spinlock.
// It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
//
// You can force a particular implementation by defining BOOST_LWM_USE_PTHREADS,
// BOOST_LWM_USE_CRITICAL_SECTION, or BOOST_LWM_USE_SPINLOCK.
//
// If neither macro has been defined, the default is to use a spinlock on Win32,
// and a pthread_mutex otherwise.
//
// Note that a spinlock is not a general synchronization primitive. In particular,
// it is not guaranteed to be a memory barrier, and it is possible to "livelock"
// if a lower-priority thread has acquired the spinlock but a higher-priority
// thread is spinning trying to acquire the same lock.
//
// For these reasons, spinlocks have been disabled by default except on Windows,
// where a spinlock can be several orders of magnitude faster than a CRITICAL_SECTION.
// Note: lwm_linux.hpp has been disabled by default; see the comments
// inside for more info.
#include <boost/config.hpp>
// Note to implementors: if you write a platform-specific spinlock
// for a platform that supports pthreads, be sure to test its performance
// against the pthreads-based version using shared_ptr_timing_test.cpp and
// shared_ptr_mt_test.cpp. Custom versions are usually not worth the trouble
// _unless_ the performance gains are substantial.
//
// Be sure to compare against a "real" pthreads library;
// shared_ptr_timing_test.cpp will compile succesfully with a stub do-nothing
// pthreads library, since it doesn't create any threads.
#ifndef BOOST_HAS_THREADS
# include <boost/detail/lwm_nop.hpp>
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(BOOST_USE_ASM_ATOMIC_H)
# include <boost/detail/lwm_linux.hpp>
#elif defined(BOOST_LWM_USE_CRITICAL_SECTION)
# include <boost/detail/lwm_win32_cs.hpp>
#elif defined(BOOST_LWM_USE_PTHREADS)
# include <boost/detail/lwm_pthreads.hpp>
#if !defined(BOOST_HAS_THREADS)
# include <boost/detail/lwm_nop.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/lwm_win32.hpp>
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__sgi)
# include <boost/detail/lwm_irix.hpp>
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__GLIBCPP__)
# include <boost/detail/lwm_gcc.hpp>
# include <boost/detail/lwm_win32_cs.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_LWM_USE_PTHREADS
# include <boost/detail/lwm_pthreads.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error

View File

@ -1,78 +0,0 @@
#ifndef BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
#define BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
//
// boost/detail/lwm_gcc.hpp
//
// lightweight_mutex for GNU libstdc++ v3
//
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2002 Lars Gullik Bj<42>nnes <larsbj@lyx.org>
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
#include <bits/atomicity.h>
#include <sched.h>
namespace boost
{
namespace detail
{
class lightweight_mutex
{
private:
_Atomic_word a_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex(): a_(1)
{
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
lightweight_mutex & m_;
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
while( !__exchange_and_add(&m_.a_, -1) )
{
__atomic_add(&m_.a_, 1);
sched_yield();
}
}
~scoped_lock()
{
__atomic_add(&m_.a_, 1);
}
};
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_LWM_GCC_HPP_INCLUDED

View File

@ -1,78 +0,0 @@
#ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
#define BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
//
// boost/detail/lwm_irix.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2002 Dan Gohman
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
#include <sgidefs.h>
#include <mutex.h>
#include <sched.h>
namespace boost
{
namespace detail
{
class lightweight_mutex
{
private:
__uint32_t l_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex(): l_(0)
{
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
lightweight_mutex & m_;
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
while( test_and_set32(&m_.l_, 1) )
{
sched_yield();
}
}
~scoped_lock()
{
m_.l_ = 0;
}
};
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED

View File

@ -1,89 +0,0 @@
#ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
#define BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
//
// boost/detail/lwm_linux.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//
// This implementation uses <asm/atomic.h>. This is a kernel header;
// using kernel headers in a user program may cause a number of problems,
// and not all flavors of Linux provide the atomic instructions.
//
// This file is only provided because the performance of this implementation
// is about 3.5 times higher than the pthreads version. Use at your own risk
// (by defining BOOST_USE_ASM_ATOMIC_H.)
//
#include <asm/atomic.h>
#include <sched.h>
namespace boost
{
namespace detail
{
class lightweight_mutex
{
private:
atomic_t a_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex()
{
atomic_t a = ATOMIC_INIT(1);
a_ = a;
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
lightweight_mutex & m_;
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
while( !atomic_dec_and_test(&m_.a_) )
{
atomic_inc(&m_.a_);
sched_yield();
}
}
~scoped_lock()
{
atomic_inc(&m_.a_);
}
};
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED

View File

@ -1,8 +1,10 @@
#ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
#define BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
@ -10,10 +12,9 @@
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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

View File

@ -1,8 +1,10 @@
#ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
#define BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
@ -10,10 +12,9 @@
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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>

View File

@ -1,121 +0,0 @@
#ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
#define BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
//
// boost/detail/lwm_win32.hpp
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
#ifdef BOOST_USE_WINDOWS_H
# include <windows.h>
#endif
#ifdef __BORLANDC__
# pragma warn -8027 // Functions containing while are not expanded inline
#endif
namespace boost
{
namespace detail
{
#ifndef BOOST_USE_WINDOWS_H
#ifdef _WIN64
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
extern "C" long_type __cdecl _InterlockedExchange(long volatile *, long);
#pragma intrinsic(_InterlockedExchange)
inline long InterlockedExchange(long volatile* lp, long l)
{
return _InterlockedExchange(lp, l);
}
#else // _WIN64
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
#endif // _WIN64
extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
#endif // #ifndef BOOST_USE_WINDOWS_H
class lightweight_mutex
{
private:
long l_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex(): l_(0)
{
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
lightweight_mutex & m_;
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
while( InterlockedExchange(&m_.l_, 1) )
{
// Note: changed to Sleep(1) from Sleep(0).
// According to MSDN, Sleep(0) will never yield
// to a lower-priority thread, whereas Sleep(1)
// will. Performance seems not to be affected.
Sleep(1);
}
}
~scoped_lock()
{
InterlockedExchange(&m_.l_, 0);
// Note: adding a yield here will make
// the spinlock more fair and will increase the overall
// performance of some applications substantially in
// high contention situations, but will penalize the
// low contention / single thread case up to 5x
}
};
};
} // namespace detail
} // namespace boost
#ifdef __BORLANDC__
# pragma warn .8027 // Functions containing while are not expanded inline
#endif
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED

View File

@ -1,8 +1,10 @@
#ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
@ -10,10 +12,9 @@
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifdef BOOST_USE_WINDOWS_H

View File

@ -7,10 +7,9 @@
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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.
//

View File

@ -1,301 +1,45 @@
#ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
#define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
// 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
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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>
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
#endif
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/detail/lightweight_mutex.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#include <boost/detail/quick_allocator.hpp>
#endif
#include <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 <exception> // std::exception
#include <new> // std::bad_alloc
#include <typeinfo> // std::type_info in get_deleter
#include <cstddef> // std::size_t
#ifdef __BORLANDC__
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
# pragma warn -8027 // Functions containing try are not expanded inline
#endif
namespace boost
{
// Debug hooks
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn);
void sp_array_constructor_hook(void * px);
void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn);
void sp_array_destructor_hook(void * px);
#endif
// The standard library that comes with Borland C++ 5.5.1
// defines std::exception and its members as having C calling
// convention (-pc). When the definition of bad_weak_ptr
// is compiled with -ps, the compiler issues an error.
// Hence, the temporary #pragma option -pc below. The version
// check is deliberately conservative.
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
# pragma option push -pc
#endif
class bad_weak_ptr: public std::exception
{
public:
virtual char const * what() const throw()
{
return "boost::bad_weak_ptr";
}
};
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
# pragma option pop
#endif
namespace detail
{
class sp_counted_base
{
private:
typedef detail::lightweight_mutex mutex_type;
public:
sp_counted_base(): use_count_(1), weak_count_(1)
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destruct() is called when weak_count_ drops to zero.
virtual void destruct() // nothrow
{
delete this;
}
virtual void * get_deleter(std::type_info const & ti) = 0;
void add_ref()
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
if(use_count_ == 0 && weak_count_ != 0) boost::throw_exception(boost::bad_weak_ptr());
++use_count_;
++weak_count_;
}
void release() // nothrow
{
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
long new_use_count = --use_count_;
if(new_use_count != 0)
{
--weak_count_;
return;
}
}
dispose();
weak_release();
}
void weak_add_ref() // nothrow
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
++weak_count_;
}
void weak_release() // nothrow
{
long new_weak_count;
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
new_weak_count = --weak_count_;
}
if(new_weak_count == 0)
{
destruct();
}
}
long use_count() const // nothrow
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
return use_count_;
}
private:
sp_counted_base(sp_counted_base const &);
sp_counted_base & operator= (sp_counted_base const &);
// inv: use_count_ <= weak_count_
long use_count_;
long weak_count_;
#if defined(BOOST_HAS_THREADS)
mutable mutex_type mtx_;
#endif
};
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
{
boost::sp_scalar_constructor_hook(px, sizeof(T), pn);
}
template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
{
boost::sp_array_constructor_hook(px);
}
template<class P, class D> void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long)
{
}
template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
{
boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
}
template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
{
boost::sp_array_destructor_hook(px);
}
template<class P, class D> void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long)
{
}
#endif
//
// Borland's Codeguard trips up over the -Vx- option here:
//
#ifdef __CODEGUARD__
# pragma option push -Vx-
#endif
template<class P, class D> class sp_counted_base_impl: public sp_counted_base
{
private:
P ptr; // copy constructor must not throw
D del; // copy constructor must not throw
sp_counted_base_impl(sp_counted_base_impl const &);
sp_counted_base_impl & operator= (sp_counted_base_impl const &);
typedef sp_counted_base_impl<P, D> this_type;
public:
// pre: initial_use_count <= initial_weak_count, d(p) must not throw
sp_counted_base_impl(P p, D d): ptr(p), del(d)
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
detail::cbi_call_constructor_hook(this, p, d, 0);
#endif
}
virtual void dispose() // nothrow
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
detail::cbi_call_destructor_hook(this, ptr, del, 0);
#endif
del(ptr);
}
virtual void * get_deleter(std::type_info const & ti)
{
return ti == typeid(D)? &del: 0;
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new(std::size_t)
{
return std::allocator<this_type>().allocate(1, static_cast<this_type *>(0));
}
void operator delete(void * p)
{
std::allocator<this_type>().deallocate(static_cast<this_type *>(p), 1);
}
#endif
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
void * operator new(std::size_t)
{
return quick_allocator<this_type>::alloc();
}
void operator delete(void * p)
{
quick_allocator<this_type>::dealloc(p);
}
#endif
};
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int const shared_count_id = 0x2C35F101;
@ -326,6 +70,36 @@ public:
{
}
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)
@ -335,7 +109,7 @@ public:
try
{
pi_ = new sp_counted_base_impl<P, D>(p, d);
pi_ = new sp_counted_impl_pd<P, D>(p, d);
}
catch(...)
{
@ -345,7 +119,7 @@ public:
#else
pi_ = new sp_counted_base_impl<P, D>(p, d);
pi_ = new sp_counted_impl_pd<P, D>(p, d);
if(pi_ == 0)
{
@ -361,11 +135,20 @@ public:
// auto_ptr<Y> is special cased to provide the strong guarantee
template<class Y>
explicit shared_count(std::auto_ptr<Y> & r): pi_(new sp_counted_base_impl< Y *, checked_deleter<Y> >(r.get(), checked_deleter<Y>()))
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();
}
@ -373,7 +156,7 @@ public:
~shared_count() // nothrow
{
if(pi_ != 0) pi_->release();
if( pi_ != 0 ) pi_->release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
id_ = 0;
#endif
@ -384,7 +167,7 @@ public:
, id_(shared_count_id)
#endif
{
if(pi_ != 0) pi_->add_ref();
if( pi_ != 0 ) pi_->add_ref_copy();
}
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
@ -392,9 +175,13 @@ public:
shared_count & operator= (shared_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if(tmp != 0) tmp->add_ref();
if(pi_ != 0) pi_->release();
pi_ = tmp;
if( tmp != pi_ )
{
if( tmp != 0 ) tmp->add_ref_copy();
if( pi_ != 0 ) pi_->release();
pi_ = tmp;
}
return *this;
}
@ -423,19 +210,15 @@ public:
friend inline bool operator<(shared_count const & a, shared_count const & b)
{
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
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;
return pi_? pi_->get_deleter( ti ): 0;
}
};
#ifdef __CODEGUARD__
# pragma option pop
#endif
class weak_count
{
@ -525,18 +308,14 @@ public:
}
};
inline shared_count::shared_count(weak_count const & r): pi_(r.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)
if( pi_ == 0 || !pi_->add_ref_lock() )
{
pi_->add_ref();
}
else
{
boost::throw_exception(boost::bad_weak_ptr());
boost::throw_exception( boost::bad_weak_ptr() );
}
}
@ -546,7 +325,6 @@ inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
#ifdef __BORLANDC__
# pragma warn .8027 // Functions containing try are not expanded inline
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
#endif
#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED

View File

@ -7,10 +7,9 @@
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
//

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

@ -0,0 +1,170 @@
#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
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <typeinfo>
namespace boost
{
namespace detail
{
inline void atomic_increment( register long * pw )
{
register int a;
asm
{
loop:
lwarx a, 0, pw
addi a, a, 1
stwcx. a, 0, pw
bne- loop
}
}
inline long atomic_decrement( register long * pw )
{
register int a;
asm
{
sync
loop:
lwarx a, 0, pw
addi a, a, -1
stwcx. a, 0, pw
bne- loop
isync
}
return a;
}
inline long atomic_conditional_increment( register long * pw )
{
register int a;
asm
{
loop:
lwarx a, 0, pw
cmpwi a, 0
beq store
addi a, a, 1
store:
stwcx. a, 0, pw
bne- loop
}
return a;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED

View File

@ -0,0 +1,158 @@
#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
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
// Copyright 2005 Rene Rivera
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <typeinfo>
namespace boost
{
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
{
// int r = *pw;
// *pw += dv;
// return r;
asm
{
mov esi, [pw]
mov eax, dv
lock xadd dword ptr [esi], eax
}
}
inline void atomic_increment( int * pw )
{
//atomic_exchange_and_add( pw, 1 );
asm
{
mov esi, [pw]
lock inc dword ptr [esi]
}
}
inline int atomic_conditional_increment( int * pw )
{
// int rv = *pw;
// if( rv != 0 ) ++*pw;
// return rv;
asm
{
mov esi, [pw]
mov eax, dword ptr [esi]
L0:
test eax, eax
je L1
mov ebx, eax
inc ebx
lock cmpxchg dword ptr [esi], ebx
jne L0
L1:
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED

View File

@ -0,0 +1,157 @@
#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-2005 Peter Dimov
// Copyright 2005 Ben Hutchings
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <typeinfo>
namespace boost
{
namespace detail
{
inline void atomic_increment( long * pw )
{
// ++*pw;
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__ ("fetchadd8.rel %0=[%2],1" :
"=r"(tmp), "=m"(*pw) :
"r"(pw));
}
inline long atomic_decrement( long * pw )
{
// return --*pw;
long rv;
__asm__ (" fetchadd8.rel %0=[%2],-1 ;; \n"
" cmp.eq p7,p0=1,%0 ;; \n"
"(p7) ld8.acq %0=[%2] " :
"=&r"(rv), "=m"(*pw) :
"r"(pw) :
"p7");
return rv;
}
inline long atomic_conditional_increment( long * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
long rv, tmp, tmp2;
__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"
" 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) :
"r"(pw) :
"ar.ccv", "p7");
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED

View File

@ -0,0 +1,181 @@
#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
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <typeinfo>
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
int tmp;
__asm__
(
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"addi %1, %1, 1\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b":
"=m"( *pw ), "=&b"( tmp ):
"r"( pw ):
"cc"
);
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int rv;
__asm__ __volatile__
(
"sync\n\t"
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"addi %1, %1, -1\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b\n\t"
"isync":
"=m"( *pw ), "=&b"( rv ):
"r"( pw ):
"memory", "cc"
);
return rv;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv;
__asm__
(
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"cmpwi %1, 0\n\t"
"beq 1f\n\t"
"addi %1, %1, 1\n\t"
"1:\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b":
"=m"( *pw ), "=&b"( rv ):
"r"( pw ):
"cc"
);
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( std::type_info const & ti ) = 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_PPC_HPP_INCLUDED

View File

@ -0,0 +1,173 @@
#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
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <typeinfo>
namespace boost
{
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
{
// int r = *pw;
// *pw += dv;
// return r;
int r;
__asm__ __volatile__
(
"lock\n\t"
"xadd %1, %0":
"=m"( *pw ), "=r"( r ): // outputs (%0, %1)
"m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
"memory", "cc" // clobbers
);
return r;
}
inline void atomic_increment( int * pw )
{
//atomic_exchange_and_add( pw, 1 );
__asm__
(
"lock\n\t"
"incl %0":
"=m"( *pw ): // output (%0)
"m"( *pw ): // input (%1)
"cc" // clobbers
);
}
inline int atomic_conditional_increment( int * pw )
{
// int rv = *pw;
// if( rv != 0 ) ++*pw;
// return rv;
int rv, tmp;
__asm__
(
"movl %0, %%eax\n\t"
"0:\n\t"
"test %%eax, %%eax\n\t"
"je 1f\n\t"
"movl %%eax, %2\n\t"
"incl %2\n\t"
"lock\n\t"
"cmpxchgl %2, %0\n\t"
"jne 0b\n\t"
"1:":
"=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
"m"( *pw ): // input (%3)
"cc" // clobbers
);
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED

View File

@ -0,0 +1,107 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_nt.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <typeinfo>
namespace boost
{
namespace detail
{
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
++use_count_;
}
bool add_ref_lock() // true on success
{
if( use_count_ == 0 ) return false;
++use_count_;
return true;
}
void release() // nothrow
{
if( --use_count_ == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
++weak_count_;
}
void weak_release() // nothrow
{
if( --weak_count_ == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return use_count_;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED

View File

@ -0,0 +1,135 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_pt.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <typeinfo>
#include <pthread.h>
namespace boost
{
namespace detail
{
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
mutable pthread_mutex_t m_;
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
#if defined(__hpux) && defined(_DECTHREADS_)
pthread_mutex_init( &m_, pthread_mutexattr_default );
#else
pthread_mutex_init( &m_, 0 );
#endif
}
virtual ~sp_counted_base() // nothrow
{
pthread_mutex_destroy( &m_ );
}
// 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( std::type_info const & ti ) = 0;
void add_ref_copy()
{
pthread_mutex_lock( &m_ );
++use_count_;
pthread_mutex_unlock( &m_ );
}
bool add_ref_lock() // true on success
{
pthread_mutex_lock( &m_ );
bool r = use_count_ == 0? false: ( ++use_count_, true );
pthread_mutex_unlock( &m_ );
return r;
}
void release() // nothrow
{
pthread_mutex_lock( &m_ );
long new_use_count = --use_count_;
pthread_mutex_unlock( &m_ );
if( new_use_count == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
pthread_mutex_lock( &m_ );
++weak_count_;
pthread_mutex_unlock( &m_ );
}
void weak_release() // nothrow
{
pthread_mutex_lock( &m_ );
long new_weak_count = --weak_count_;
pthread_mutex_unlock( &m_ );
if( new_weak_count == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
pthread_mutex_lock( &m_ );
long r = use_count_;
pthread_mutex_unlock( &m_ );
return r;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED

View File

@ -0,0 +1,117 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_w32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/detail/interlocked.hpp>
#include <typeinfo>
namespace boost
{
namespace detail
{
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( std::type_info const & ti ) = 0;
void add_ref_copy()
{
BOOST_INTERLOCKED_INCREMENT( &use_count_ );
}
bool add_ref_lock() // true on success
{
for( ;; )
{
long tmp = static_cast< long const volatile& >( use_count_ );
if( tmp == 0 ) return false;
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
}
}
void release() // nothrow
{
if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
}
void weak_release() // nothrow
{
if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED

View File

@ -0,0 +1,187 @@
#ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_impl.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/config.hpp>
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
#endif
#include <boost/checked_delete.hpp>
#include <boost/detail/sp_counted_base.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#include <boost/detail/quick_allocator.hpp>
#endif
#include <memory> // std::allocator
#include <typeinfo> // std::type_info in get_deleter
#include <cstddef> // std::size_t
namespace boost
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
#endif
namespace detail
{
template<class X> class sp_counted_impl_p: public sp_counted_base
{
private:
X * px_;
sp_counted_impl_p( sp_counted_impl_p const & );
sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
typedef sp_counted_impl_p<X> this_type;
public:
explicit sp_counted_impl_p( X * px ): px_( px )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px, sizeof(X), this );
#endif
}
virtual void dispose() // nothrow
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
#endif
boost::checked_delete( px_ );
}
virtual void * get_deleter( std::type_info const & )
{
return 0;
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new( std::size_t )
{
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
}
void operator delete( void * p )
{
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
}
#endif
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
void * operator new( std::size_t )
{
return quick_allocator<this_type>::alloc();
}
void operator delete( void * p )
{
quick_allocator<this_type>::dealloc( p );
}
#endif
};
//
// Borland's Codeguard trips up over the -Vx- option here:
//
#ifdef __CODEGUARD__
# pragma option push -Vx-
#endif
template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
{
private:
P ptr; // copy constructor must not throw
D del; // copy constructor must not throw
sp_counted_impl_pd( sp_counted_impl_pd const & );
sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
typedef sp_counted_impl_pd<P, D> this_type;
public:
// pre: d(p) must not throw
sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
{
}
virtual void dispose() // nothrow
{
del( ptr );
}
virtual void * get_deleter( std::type_info const & ti )
{
return ti == typeid(D)? &del: 0;
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new( std::size_t )
{
return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
}
void operator delete( void * p )
{
std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
}
#endif
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
void * operator new( std::size_t )
{
return quick_allocator<this_type>::alloc();
}
void operator delete( void * p )
{
quick_allocator<this_type>::dealloc( p );
}
#endif
};
#ifdef __CODEGUARD__
# pragma option pop
#endif
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED

View File

@ -6,10 +6,9 @@
//
// Copyright (c) 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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
//
@ -24,6 +23,25 @@ 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()
@ -41,7 +59,7 @@ public:
}
typedef T _internal_element_type; // for bcc 5.5.1
weak_ptr<_internal_element_type> _internal_weak_this;
mutable weak_ptr<_internal_element_type> _internal_weak_this;
};
} // namespace boost

View File

@ -1,8 +1,7 @@
// Copyright Peter Dimov and David Abrahams 2002. Permission to copy,
// use, modify, sell and distribute this software is granted provided
// this copyright notice appears in all copies of the source. This
// software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// Copyright Peter Dimov and David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef GET_POINTER_DWA20021219_HPP
# define GET_POINTER_DWA20021219_HPP

View File

@ -6,14 +6,15 @@
//
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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>
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
# pragma warning(push)
# pragma warning(disable:4284) // odd return type for operator->
@ -119,13 +120,32 @@ public:
return p_;
}
typedef T * (intrusive_ptr::*unspecified_bool_type) () const;
#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: &intrusive_ptr::get;
return p_ == 0? 0: &this_type::p_;
}
#endif
// operator! is a Borland-specific workaround
bool operator! () const
{
@ -207,6 +227,11 @@ template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U>
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());
@ -224,7 +249,7 @@ template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y>
#else
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
# 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)

View File

@ -4,10 +4,9 @@
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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
//
@ -15,6 +14,9 @@
#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
@ -83,13 +85,32 @@ public:
// implicit conversion to "bool"
typedef T * (this_type::*unspecified_bool_type)() const;
#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;

View File

@ -4,16 +4,16 @@
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/detail/workaround.hpp>
#ifndef BOOST_NO_AUTO_PTR
# include <memory> // for std::auto_ptr
@ -102,13 +102,31 @@ public:
// implicit conversion to "bool"
typedef T * (this_type::*unspecified_bool_type)() const;
#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;

View File

@ -7,10 +7,9 @@
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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.
//
@ -25,6 +24,7 @@
#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
@ -94,13 +94,32 @@ public:
// implicit conversion to "bool"
typedef T * (this_type::*unspecified_bool_type)() const;
#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;

View File

@ -7,10 +7,9 @@
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
//
@ -48,6 +47,7 @@ namespace detail
{
struct static_cast_tag {};
struct const_cast_tag {};
struct dynamic_cast_tag {};
struct polymorphic_cast_tag {};
@ -68,16 +68,26 @@ 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(boost::enable_shared_from_this<T> * pe, Y * px, shared_count const & pn)
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(px, pn);
if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
}
inline void sp_enable_shared_from_this(void const *, void const *, shared_count const &)
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
{
}
@ -111,9 +121,9 @@ public:
}
template<class Y>
explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
{
detail::sp_enable_shared_from_this(p, p, pn);
detail::sp_enable_shared_from_this( pn, p, p );
}
//
@ -124,7 +134,7 @@ public:
template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
{
detail::sp_enable_shared_from_this(p, p, pn);
detail::sp_enable_shared_from_this( pn, p, p );
}
// generated copy constructor, assignment, destructor are fine...
@ -158,6 +168,11 @@ public:
{
}
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)
{
@ -183,7 +198,7 @@ public:
{
Y * tmp = r.get();
pn = detail::shared_count(r);
detail::sp_enable_shared_from_this(tmp, tmp, pn);
detail::sp_enable_shared_from_this( pn, tmp, tmp );
}
#endif
@ -246,13 +261,35 @@ public:
// implicit conversion to "bool"
typedef T * (this_type::*unspecified_bool_type)() const;
#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
@ -340,6 +377,11 @@ template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const
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());
@ -387,7 +429,7 @@ template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> co
#else
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
# 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)
@ -403,9 +445,12 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
// get_deleter (experimental)
#if defined(__GNUC__) && (__GNUC__ < 3)
#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)
{

View File

@ -1,20 +1,25 @@
//
// smart_ptr.hpp
//
// For compatibility, this header includes the headers for the four "classic"
// smart pointer class templates.
// For convenience, this header includes the rest of the smart
// pointer library headers.
//
// Copyright (c) 1998-2002 boost.org
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// 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)
//
// http://www.boost.org/libs/smart_ptr/smart_ptr.htm
//
#include <boost/scoped_ptr.hpp>
#include <boost/config.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
# include <boost/weak_ptr.hpp>
# include <boost/intrusive_ptr.hpp>
# include <boost/enable_shared_from_this.hpp>
#endif

View File

@ -6,10 +6,9 @@
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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.
//

View File

@ -1,51 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Boost Smart Pointer Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2">
<tr>
<td bgcolor="#FFFFFF"><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font face="Arial" color="#FFFFFF"><big>Home</big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries</big></font></a></td>
<td><a href="../../people/people.htm"><font face="Arial" color="#FFFFFF"><big>People</big></font></a></td>
<td><a href="../../more/faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ</big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color="#FFFFFF"><big>More</big></font></a></td>
</tr>
</table>
<h1>Smart Pointer Library</h1>
<p>The smart pointer library includes five smart pointer class templates. Smart
pointers ease the management of memory dynamically allocated with C++ <b>new</b>
expressions. In addition, <b>scoped_ptr</b> can ease the management of memory
dynamically allocated in other ways.</p>
<ul>
<li>
<a href="smart_ptr.htm">Documentation</a> (HTML).</li>
<li>
Header <a href="../../boost/scoped_ptr.hpp">scoped_ptr.hpp</a>.</li>
<li>
Header <a href="../../boost/scoped_array.hpp">scoped_array.hpp</a>.</li>
<li>
Header <a href="../../boost/shared_ptr.hpp">shared_ptr.hpp</a>.</li>
<li>
Header <a href="../../boost/shared_array.hpp">shared_array.hpp</a>.</li>
<li>
Header <a href="../../boost/weak_ptr.hpp">weak_ptr.hpp</a>.</li>
<li>
Header <a href="../../boost/enable_shared_from_this.hpp">enable_shared_from_this.hpp</a>.</li>
<li>
Header <a href="../../boost/intrusive_ptr.hpp">intrusive_ptr.hpp</a>.</li>
<li>
Test program <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>.</li>
<li>
Originally submitted by <a href="../../people/greg_colvin.htm">Greg Colvin</a> and
<a href="../../people/beman_dawes.html">Beman Dawes</a>, currently maintained
by <a href="../../people/peter_dimov.htm">Peter Dimov</a> and <a href="../../people/darin_adler.htm">
Darin Adler</a>.</li>
</ul>
<hr>
<p>$Date$</p>
</body>
</html>

9
index.html Normal file
View File

@ -0,0 +1,9 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=smart_ptr.htm">
</head>
<body>
Automatic redirection failed, please go to
<a href="smart_ptr.htm">smart_ptr.htm</a>.
</body>
</html>

View File

@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">intrusive_ptr
<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>
@ -100,6 +100,9 @@
template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <A href="#static_pointer_cast" >static_pointer_cast</A>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <A href="#const_pointer_cast" >const_pointer_cast</A>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <A href="#dynamic_pointer_cast" >dynamic_pointer_cast</A>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
@ -250,6 +253,13 @@ intrusive_ptr &amp; operator=(T * r);</pre>
<P><B>Returns:</B> <code>intrusive_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code>.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; const_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<BLOCKQUOTE>
<P><B>Returns:</B> <code>intrusive_ptr&lt;T&gt;(const_cast&lt;T*&gt;(r.get()))</code>.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; dynamic_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r);</pre>

View File

@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86"><a name="scoped_array">scoped_array</a>
<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>

View File

@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86"><a name="scoped_ptr">scoped_ptr</a>
<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.)
@ -115,7 +115,7 @@ class MyClass {
int add_one() { return ++*ptr; }
};
void main()
int main()
{
boost::scoped_ptr&lt;Shoe&gt; x(new Shoe);
MyClass my_instance;

View File

@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">shared_array
<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>

View File

@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">shared_ptr
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle">shared_ptr
class template</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#BestPractices">Best Practices</A><br>
@ -20,7 +20,7 @@
<A href="sp_techniques.html">Programming Techniques</A></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <b>shared_ptr</b> class template stores a pointer to a dynamically allocated
object, typically with a C++ <EM>new-expression</EM> . The object pointed to is
object, typically with a C++ <EM>new-expression</EM>. The object pointed to is
guaranteed to be deleted when the last <b>shared_ptr</b> pointing to it is
destroyed or reset. See the <A href="#example">example</A>.</p>
<p>Every <b>shared_ptr</b> meets the <b>CopyConstructible</b> and <b>Assignable</b>
@ -47,6 +47,13 @@
to <STRONG>shared_ptr&lt;T const&gt;</STRONG>, to <STRONG>shared_ptr&lt;U&gt;</STRONG>
where <STRONG>U</STRONG> is an accessible base of <STRONG>T</STRONG>, and to <STRONG>
shared_ptr&lt;void&gt;</STRONG>.</P>
<P><STRONG>shared_ptr</STRONG> is now part of <STRONG>TR1</STRONG>, the first C++
Library Technical Report. The latest draft of <STRONG>TR1</STRONG> is available
at the following location:</P>
<P><A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf</A>
(1.36Mb PDF)</P>
<P>This implementation conforms to the TR1 specification, with the only exception
that it resides in namespace <code>boost</code> instead of <code>std::tr1</code>.</P>
<h2><a name="BestPractices">Best Practices</a></h2>
<P>A simple guideline that nearly eliminates the possibility of memory leaks is:
always use a named smart pointer variable to hold the result of <STRONG>new. </STRONG>
@ -142,6 +149,9 @@ void bad()
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; <A href="#static_pointer_cast" >static_pointer_cast</A>(shared_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; <A href="#const_pointer_cast" >const_pointer_cast</A>(shared_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; <A href="#dynamic_pointer_cast" >dynamic_pointer_cast</A>(shared_ptr&lt;U&gt; const &amp; r); // never throws
@ -151,15 +161,6 @@ void bad()
template&lt;class D, class T&gt;
D * <A href="#get_deleter">get_deleter</A>(shared_ptr&lt;T&gt; const &amp; p);
}</pre>
<P><EM>[It might be convenient to relax the requirements on <STRONG>shared_ptr</STRONG>'s
signature, allowing an additional, defaulted, template parameter; the parameter
can encode the threading model, for example. This would help in detecting
possible ODR violations.</EM></P>
<P><EM>On the other hand, using <STRONG>shared_ptr</STRONG> as an argument to a
template template parameter requires an exact signature match. </EM><EM>Metaprogramming
experts tend to deemphasize template template parameters as they are too
inflexible, but the alternative is typically an std::allocator::rebind-type
"hack".]</EM></P>
<h2><a name="Members">Members</a></h2>
<h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
@ -169,24 +170,13 @@ void bad()
<h3><a name="constructors">constructors</a></h3>
<pre>shared_ptr(); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Constructs an <EM>empty</EM> <b>shared_ptr</b>. <EM>Empty</EM> <STRONG>
shared_ptr</STRONG> objects have an unspecified <A href="#use_count">use_count</A>.</p>
<p><b>Postconditions:</b> <code>get() == 0</code>.</p>
<p><b>Effects:</b> Constructs an <EM>empty</EM> <b>shared_ptr</b>.</p>
<p><b>Postconditions:</b> <code>use_count() == 0 &amp;&amp; get() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<P><EM>[The nothrow guarantee is important, since <STRONG>reset()</STRONG> is specified
in terms of the default constructor; this implies that the constructor must not
allocate memory.</EM></P>
<P><EM>There are two possible implementations, one stores 0 as a pointer to the
reference count, the other uses a single statically allocated count for all
default-constructed <STRONG>shared_ptr</STRONG>s. The second option is
difficult to achieve in the current header-only reference implementation due to
thread safety issues and initialization order, but it should not be precluded
by the specification. That's why the use_count() has been left unspecified.</EM></P>
<P><EM>A future release may enable <STRONG>shared_ptr</STRONG> construction from a
literal zero, for consistency with built-in pointers. It is not clear yet
whether this constructor should be left implicit, enabling <STRONG>0</STRONG> to
be used as a shorthand for <STRONG>shared_ptr&lt;T&gt;().</STRONG>]</EM></P>
allocate memory.]</EM></P>
<pre>template&lt;class Y&gt; explicit shared_ptr(Y * p);</pre>
<blockquote>
<p><b>Requirements:</b> <b>p</b> must be convertible to <b>T *</b>. <STRONG>Y</STRONG>
@ -195,8 +185,8 @@ void bad()
</p>
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <b>p</b>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p>
<p><b>Throws:</b> <b>std::bad_alloc</b> or an implementation-defined exception when
a resource other than memory could not be obtained.</p>
<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, <code>delete p</code> is
called.</p>
<P><STRONG>Notes:</STRONG> <B>p</B> must be a pointer to an object that was
@ -223,8 +213,8 @@ void bad()
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <STRONG>
p</STRONG> and the deleter <b>d</b>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p>
<p><b>Throws:</b> <b>std::bad_alloc</b> or an implementation-defined exception when
a resource other than memory could not be obtained.</p>
<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</p>
<p><b>Notes:</b> When the the time comes to delete the object pointed to by <b>p</b>,
the stored copy of <STRONG>d</STRONG> is invoked with the stored copy of <STRONG>p</STRONG>
@ -242,17 +232,10 @@ void bad()
<P><EM>The requirement that the copy constructor of <b>D</b> does not throw comes from
the pass by value. If the copy constructor throws, the pointer is leaked.
Removing the requirement requires a pass by (const) reference.</EM></P>
<P><EM>Pass by reference is problematic since (1) pass by value conveniently changes
functions (function references) to function pointers (this has to be performed
manually otherwise and some compilers may not be able to do it) and (2) const
references don't currently (per the standard) bind to functions. This can be
solved (I think) but it requires an overload set that breaks on many compilers
due to 14.5.5.2 problems (and of course it will break on compilers that don't
do partial ordering at all.)</EM></P>
<P><EM>The main problem with pass by reference, though, lies in its interaction with
rvalues. A const reference may still cause a copy, and will require a const
operator(). A non-const reference won't bind to an rvalue at all. A good
solution to this problem is the rvalue reference proposed in <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">
<P><EM>The main problem with pass by reference lies in its interaction with rvalues. A
const reference may still cause a copy, and will require a const operator(). A
non-const reference won't bind to an rvalue at all. A good solution to this
problem is the rvalue reference proposed in <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">
N1377</A>/<A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">N1385</A>.]</EM></P>
<pre>shared_ptr(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
@ -265,9 +248,8 @@ template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never
</blockquote>
<pre>template&lt;class Y&gt; explicit shared_ptr(<A href="weak_ptr.htm" >weak_ptr</A>&lt;Y&gt; const &amp; r);</pre>
<blockquote>
<p><b>Effects:</b> If <b>r</b> is <EM>empty</EM>, constructs an <EM>empty</EM> <b>shared_ptr</b>;
otherwise, constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with <b>r</b>
and stores a copy of the pointer stored in <STRONG>r</STRONG>.</p>
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with
<b>r</b> and stores a copy of the pointer stored in <STRONG>r</STRONG>.</p>
<p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p>
<p><b>Throws:</b> <b>bad_weak_ptr</b> when <code>r.use_count() == 0</code>.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor has no
@ -277,8 +259,8 @@ template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never
<BLOCKQUOTE>
<P><B>Effects:</B> Constructs a <B>shared_ptr</B>, as if by storing a copy of <STRONG>r.release()</STRONG>.</P>
<p><b>Postconditions:</b> <code>use_count() == 1</code>.</p>
<p><b>Throws:</b> <b>std::bad_alloc</b> or an implementation-defined exception when
a resource other than memory could not be obtained.</p>
<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<P><B>Exception safety:</B> If an exception is thrown, the constructor has no
effect.</P>
</BLOCKQUOTE>
@ -322,12 +304,6 @@ q = p;
</pre>
<p>both assignments may be no-ops.</p>
</BLOCKQUOTE>
<P><EM>[Some experts consider the note to be redundant, as it appears to essentially
mirror the "as if" rule. However, experience suggests that when C++ code is
used to describe effects, it is often misinterpreted as required
implementation. In addition, it is not entirely clear whether the "as if" rule
actually applies here, so it's better to be explicit about the possible
optimizations.]</EM></P>
<h3><a name="reset">reset</a></h3>
<pre>void reset(); // never throws</pre>
<BLOCKQUOTE>
@ -424,7 +400,7 @@ q = p;
<LI>
under the equivalence relation defined by <STRONG>operator&lt;</STRONG>, <code>!(a
&lt; b) &amp;&amp; !(b &lt; a)</code>, two <STRONG>shared_ptr</STRONG> instances
are equivalent if and only if they <EM>share ownership</EM>.</LI></UL>
are equivalent if and only if they <EM>share ownership</EM> or are both <EM>empty</EM>.</LI></UL>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Allows <STRONG>shared_ptr</STRONG> objects to be used as keys in
associative containers.</P>
@ -473,6 +449,21 @@ q = p;
<p>will eventually result in undefined behavior, attempting to delete the same
object twice.</p>
</BLOCKQUOTE>
<h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; const_pointer_cast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<BLOCKQUOTE>
<P><STRONG>Requires:</STRONG> The expression <code>const_cast&lt;T*&gt;(r.get())</code>
must be well-formed.</P>
<P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr&lt;T&gt;</b>;
otherwise, a <STRONG>shared_ptr&lt;T&gt;</STRONG> object that stores a copy of <code>
const_cast&lt;T*&gt;(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P>
<P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> the seemingly equivalent expression</P>
<p><code>shared_ptr&lt;T&gt;(const_cast&lt;T*&gt;(r.get()))</code></p>
<p>will eventually result in undefined behavior, attempting to delete the same
object twice.</p>
</BLOCKQUOTE>
<h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; dynamic_pointer_cast(shared_ptr&lt;U&gt; const &amp; r);</pre>
@ -584,11 +575,32 @@ p3.reset(new int(1));
// thread B
p3.reset(new int(2)); // undefined, multiple writes
</pre>
<p><STRONG>shared_ptr</STRONG> uses <A href="../config/config.htm">Boost.Config</A>
to detect whether the implementation supports threads. If your program is
single-threaded, but your platform is autodetected by <STRONG>Boost.Config</STRONG>
as supporting multiple threads, <STRONG>#define BOOST_DISABLE_THREADS</STRONG> to
eliminate the thread safety overhead.</p>
<p>&nbsp;</p>
<P>Starting with Boost release 1.33.0, <STRONG>shared_ptr</STRONG> uses a lock-free
implementation on the following platforms:</P>
<UL>
<LI>
GNU GCC on x86 or x86-64;
<LI>
GNU GCC on IA64;
<LI>
Metrowerks CodeWarrior on PowerPC;
<LI>
GNU GCC on PowerPC;
<LI>
Windows.</LI></UL>
<P>If your program is single-threaded and does not link to any libraries that might
have used <STRONG>shared_ptr</STRONG> in its default configuration, you can <STRONG>
#define</STRONG> the macro <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> on a
project-wide basis to switch to ordinary non-atomic reference count updates.</P>
<P>(Defining <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> in some, but not all,
translation units is technically a violation of the One Definition Rule and
undefined behavior. Nevertheless, the implementation attempts to do its best to
accommodate the request to use non-atomic updates in those translation units.
No guarantees, though.)</P>
<P>You can define the macro <STRONG>BOOST_SP_USE_PTHREADS</STRONG> to turn off the
lock-free platform-specific implementation and fall back to the generic <STRONG>pthread_mutex_t</STRONG>-based
code.</P>
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
<P><B>Q.</B> There are several variations of shared pointers, with different
tradeoffs; why does the smart pointer library supply only a single
@ -609,7 +621,7 @@ p3.reset(new int(2)); // undefined, multiple writes
day a highly configurable smart pointer may be invented that is also very easy
to use and very hard to misuse. Until then, <B>shared_ptr</B> is the smart
pointer of choice for a wide range of applications. (Those interested in policy
based smart pointers should read <A href="http://cseng.aw.com/book/0,,0201704315,00.html">
based smart pointers should read <A href="http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&rl=1">
Modern C++ Design</A> by Andrei Alexandrescu.)<BR>
</P>
<P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate
@ -673,7 +685,7 @@ int * p = a.release();
<p>
$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002, 2003 Peter Dimov. Permission to copy, use, modify, sell and
Copyright 2002-2005 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>

View File

@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Smart
<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>

View File

@ -9,7 +9,7 @@
<body bgcolor="#FFFFFF">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" WIDTH="277" HEIGHT="86">Smart Pointer Timings</h1>
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Smart Pointer Timings</h1>
<p>In late January 2000, Mark Borgerding put forward a suggestion to boost for
a new design of smart pointer whereby an intrusive doubly linked list is used

View File

@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">Smart
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle">Smart
Pointer Programming Techniques</h1>
<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
<A href="#pimpl">The "Pimpl" idiom</A><br>
@ -272,6 +272,9 @@ shared_ptr&lt;X&gt; createX()
single reference created in <code>make_shared_from_COM</code>. Weak pointers
created from <code>pw</code> will be invalidated when the last <code>shared_ptr</code>
is destroyed, regardless of whether the COM object itself is still alive.</p>
<P>As <A href="../bind/mem_fn.html#Q3">explained</A> in the <code>mem_fn</code> documentation,
you need to <A href="../bind/mem_fn.html#stdcall">#define
BOOST_MEM_FN_ENABLE_STDCALL</A> first.</P>
<h2><A name="intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object
with an embedded reference count</A></h2>
<p>This is a generalization of the above technique. The example assumes that the
@ -753,8 +756,8 @@ public:
<hr>
<p>$Date$</p>
<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>
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

@ -3,10 +3,9 @@
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)

View File

@ -3,10 +3,9 @@
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)

View File

@ -1,6 +1,6 @@
# Boost.SmartPtr Library test Jamfile
#
# Copyright (c) 2003 Peter Dimov
# Copyright (c) 2003-2005 Peter Dimov
# Copyright (c) 2003 Dave Abrahams
#
# Permission to copy, use, modify, sell and distribute this software
@ -11,8 +11,7 @@
subproject libs/smart_ptr/test ;
# bring in rules for testing
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ;
import testing ;
# Make tests run by default.
DEPENDS all : smart_ptr ;
@ -27,7 +26,10 @@ DEPENDS all : smart_ptr ;
[ run get_deleter_test.cpp ]
[ run intrusive_ptr_test.cpp ]
[ run intrusive_ptr_test.cpp ]
[ run atomic_count_test.cpp ]
[ run lw_mutex_test.cpp ]
[ compile-fail shared_ptr_assign_fail.cpp ]
[ compile-fail shared_ptr_delete_fail.cpp ]
;
# this one is too slow to run unless explicitly requested, and ALL

28
test/Jamfile.v2 Normal file
View File

@ -0,0 +1,28 @@
# Boost.SmartPtr Library test Jamfile
#
# Copyright (c) 2003-2005 Peter Dimov
# Copyright (c) 2003 Dave Abrahams
#
# Permission to copy, use, modify, sell and distribute this software
# is granted provided this copyright notice appears in all copies.
# This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
# bring in rules for testing
import testing ;
{
test-suite "smart_ptr"
: [ run smart_ptr_test.cpp ]
[ run shared_ptr_basic_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ]
[ run shared_ptr_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ]
[ run weak_ptr_test.cpp ]
[ run shared_from_this_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ]
[ run get_deleter_test.cpp ]
[ run intrusive_ptr_test.cpp ]
[ run atomic_count_test.cpp ]
[ run lw_mutex_test.cpp ]
[ compile-fail shared_ptr_assign_fail.cpp ]
[ compile-fail shared_ptr_delete_fail.cpp ]
;
}

View File

@ -0,0 +1,40 @@
//
// atomic_count_test.cpp
//
// 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/detail/atomic_count.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
boost::detail::atomic_count n( 4 );
BOOST_TEST( n == 4L );
++n;
BOOST_TEST( n == 5L );
BOOST_TEST( --n != 0L );
boost::detail::atomic_count m( 0 );
BOOST_TEST( m == 0 );
++m;
BOOST_TEST( m == 1 );
++m;
BOOST_TEST( m == 2 );
BOOST_TEST( --m != 0 );
BOOST_TEST( --m == 0 );
return boost::report_errors();
}

View File

@ -3,10 +3,9 @@
//
// Copyright (c) 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>

View File

@ -3,10 +3,9 @@
//
// Copyright (c) 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>

View File

@ -1,4 +1,7 @@
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
@ -6,21 +9,26 @@
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
#pragma warning(disable: 4511) // copy constructor could not be generated
#pragma warning(disable: 4512) // assignment operator could not be generated
#if (BOOST_MSVC >= 1310)
#pragma warning(disable: 4675) // resolved overload found with Koenig lookup
#endif
#endif
//
// intrusive_ptr_test.cpp
//
// Copyright (c) 2002, 2003 Peter Dimov
// Copyright (c) 2002-2005 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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/lightweight_test.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/detail/atomic_count.hpp>
#include <boost/config.hpp>
#include <algorithm>
#include <functional>
@ -34,7 +42,7 @@ class base
{
private:
long use_count_;
boost::detail::atomic_count use_count_;
base(base const &);
base & operator=(base const &);

28
test/lw_mutex_test.cpp Normal file
View File

@ -0,0 +1,28 @@
//
// lw_mutex_test.cpp
//
// 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/detail/lightweight_mutex.hpp>
// Sanity check only
boost::detail::lightweight_mutex m1;
int main()
{
boost::detail::lightweight_mutex::scoped_lock lock1( m1 );
boost::detail::lightweight_mutex m2;
boost::detail::lightweight_mutex m3;
boost::detail::lightweight_mutex::scoped_lock lock2( m2 );
boost::detail::lightweight_mutex::scoped_lock lock3( m3 );
return 0;
}

View File

@ -1,4 +1,6 @@
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
@ -10,10 +12,9 @@
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
@ -67,18 +68,20 @@ void test()
}
void test2();
void test3();
int main()
{
test();
test2();
test3();
return boost::report_errors();
}
// virtual inheritance from Y to stress the implementation
// (prevents Y* -> impl* casts)
// virtual inheritance to stress the implementation
// (prevents Y* -> impl*, enable_shared_from_this<impl>* -> impl* casts)
class impl: public X, public virtual Y, public boost::enable_shared_from_this<impl>
class impl: public X, public virtual Y, public virtual boost::enable_shared_from_this<impl>
{
public:
@ -110,3 +113,41 @@ void test2()
{
boost::shared_ptr<Y> pi(static_cast<impl2*>(0));
}
//
struct V: public boost::enable_shared_from_this<V>
{
};
void test3()
{
boost::shared_ptr<V> p(new V);
boost::shared_ptr<V> q = p->shared_from_this();
BOOST_TEST(p == q);
BOOST_TEST(!(p < q) && !(q < p));
V v2(*p);
try
{
boost::shared_ptr<V> r = v2.shared_from_this();
BOOST_ERROR("v2.shared_from_this() failed to throw");
}
catch(boost::bad_weak_ptr const &)
{
}
try
{
*p = V();
boost::shared_ptr<V> r = p->shared_from_this();
BOOST_TEST(p == r);
BOOST_TEST(!(p < r) && !(r < p));
}
catch(boost::bad_weak_ptr const &)
{
BOOST_ERROR("p->shared_from_this() threw bad_weak_ptr after *p = V()");
}
}

View File

@ -3,10 +3,9 @@
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>

View File

@ -1,4 +1,6 @@
#if defined(_MSC_VER) && !defined(__ICL)
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
@ -10,10 +12,9 @@
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>

View File

@ -1,12 +1,27 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
#if (BOOST_MSVC >= 1310)
#pragma warning(disable: 4675) // resolved overload found with Koenig lookup
#endif
#endif
//
// shared_ptr_basic_test.cpp
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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/lightweight_test.hpp>

View File

@ -0,0 +1,27 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
//
// shared_ptr_delete_fail.cpp - a negative test for "delete sp;"
//
// Copyright 2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>
int main()
{
boost::shared_ptr<int> p;
delete p; // must fail
return 0;
}

View File

@ -1,4 +1,6 @@
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
@ -10,10 +12,9 @@
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>
@ -142,19 +143,11 @@ void test(boost::shared_ptr<int> const & pi)
int const m = 16; // threads
#if defined(BOOST_LWM_USE_CRITICAL_SECTION)
char const * implementation = "critical section";
#elif defined(BOOST_LWM_USE_PTHREADS)
char const * implementation = "pthread_mutex";
#else
char const * implementation = "spinlock";
#endif
int main()
{
using namespace std; // printf, clock_t, clock
printf("%s: %s, %d threads, %d iterations: ", title, implementation, m, n);
printf("%s: %d threads, %d iterations: ", title, m, n);
boost::shared_ptr<int> pi(new int(42));

View File

@ -1,9 +1,17 @@
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
#if (BOOST_MSVC >= 1310)
#pragma warning(disable: 4675) // resolved overload found with Koenig lookup
#endif
#endif
//
@ -11,10 +19,9 @@
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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/lightweight_test.hpp>
@ -123,10 +130,31 @@ private:
long Y::instances = 0;
template<class T> void pc0_test(T * p)
{
BOOST_TEST(p == 0);
boost::shared_ptr<T> pt(p);
BOOST_TEST(pt? false: true);
BOOST_TEST(!pt);
BOOST_TEST(pt.get() == 0);
BOOST_TEST(pt.use_count() == 1);
BOOST_TEST(pt.unique());
}
void pointer_constructor()
{
pc0_test(static_cast<int*>(0));
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1300)
pc0_test(static_cast<int const*>(0));
pc0_test(static_cast<int volatile*>(0));
pc0_test(static_cast<int const volatile*>(0));
#endif
{
boost::shared_ptr<int> pi(static_cast<int*>(0));
boost::shared_ptr<int const> pi(static_cast<int*>(0));
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
@ -135,7 +163,7 @@ void pointer_constructor()
}
{
boost::shared_ptr<int const> pi(static_cast<int*>(0));
boost::shared_ptr<int volatile> pi(static_cast<int*>(0));
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
@ -161,14 +189,10 @@ void pointer_constructor()
BOOST_TEST(pv.unique());
}
{
boost::shared_ptr<X> px(static_cast<X*>(0));
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
}
pc0_test(static_cast<X*>(0));
pc0_test(static_cast<X const*>(0));
pc0_test(static_cast<X volatile*>(0));
pc0_test(static_cast<X const volatile*>(0));
{
boost::shared_ptr<X const> px(static_cast<X*>(0));
@ -817,6 +841,10 @@ void weak_ptr_constructor()
}
}
#if defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB < 306)
# define BOOST_OLD_AUTO_PTR
#endif
void auto_ptr_constructor()
{
{
@ -940,7 +968,7 @@ void auto_ptr_constructor()
BOOST_TEST(pi.unique());
BOOST_TEST(*pi == 7);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -956,7 +984,7 @@ void auto_ptr_constructor()
BOOST_TEST(pi.unique());
BOOST_TEST(*pi == 7);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -971,7 +999,7 @@ void auto_ptr_constructor()
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -986,7 +1014,7 @@ void auto_ptr_constructor()
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -1004,7 +1032,7 @@ void auto_ptr_constructor()
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -1022,7 +1050,7 @@ void auto_ptr_constructor()
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -1040,7 +1068,7 @@ void auto_ptr_constructor()
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -1058,7 +1086,7 @@ void auto_ptr_constructor()
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -1078,7 +1106,7 @@ void auto_ptr_constructor()
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -1098,7 +1126,7 @@ void auto_ptr_constructor()
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
@ -1407,7 +1435,7 @@ void auto_ptr_assignment()
BOOST_TEST(p1.get() == p);
BOOST_TEST(p1.use_count() == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p3.get() == 0);
#endif
@ -1436,7 +1464,7 @@ void auto_ptr_assignment()
BOOST_TEST(p1.get() == p);
BOOST_TEST(p1.use_count() == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p3.get() == 0);
#endif
@ -1473,7 +1501,7 @@ void auto_ptr_assignment()
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p3.get() == 0);
#endif
@ -2371,6 +2399,57 @@ void test()
} // namespace n_static_cast
namespace n_const_cast
{
struct X;
void test()
{
{
boost::shared_ptr<void const volatile> px;
boost::shared_ptr<void> px2 = boost::const_pointer_cast<void>(px);
BOOST_TEST(px2.get() == 0);
}
{
boost::shared_ptr<int const volatile> px;
boost::shared_ptr<int> px2 = boost::const_pointer_cast<int>(px);
BOOST_TEST(px2.get() == 0);
}
{
boost::shared_ptr<X const volatile> px;
boost::shared_ptr<X> px2 = boost::const_pointer_cast<X>(px);
BOOST_TEST(px2.get() == 0);
}
{
boost::shared_ptr<void const volatile> px(new int);
boost::shared_ptr<void> px2 = boost::const_pointer_cast<void>(px);
BOOST_TEST(px.get() == px2.get());
BOOST_TEST(!(px < px2 || px2 < px));
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(px2.use_count() == 2);
}
{
boost::shared_ptr<int const volatile> px(new int);
boost::shared_ptr<int> px2 = boost::const_pointer_cast<int>(px);
BOOST_TEST(px.get() == px2.get());
BOOST_TEST(!(px < px2 || px2 < px));
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(px2.use_count() == 2);
}
}
} // namespace n_const_cast
namespace n_dynamic_cast
{
@ -3137,6 +3216,7 @@ int main()
n_swap::test();
n_comparison::test();
n_static_cast::test();
n_const_cast::test();
n_dynamic_cast::test();
n_map::test();

View File

@ -1,4 +1,6 @@
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
@ -10,10 +12,9 @@
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>

View File

@ -1,20 +1,10 @@
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
# pragma warning(disable: 4786) // identifier truncated in debug info
# pragma warning(disable: 4710) // function not inlined
# pragma warning(disable: 4711) // function selected for automatic inline expansion
# pragma warning(disable: 4514) // unreferenced inline removed
#endif
#ifdef __BORLANDC__
# pragma warn -8092 // template argument passed to 'find' is not an iterator
#endif
// smart pointer test program ----------------------------------------------//
// (C) Copyright Beman Dawes 1998, 1999. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright notice
// appears in all copies. This software is provided "as is" without express or
// implied warranty, and with no claim as to its suitability for any purpose.
// Copyright Beman Dawes 1998, 1999. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/smart_ptr for documentation.
// Revision History
// 24 May 01 use Boost test library for error detection, reporting, add tests
@ -24,6 +14,25 @@
// 20 Jul 99 header name changed to .hpp
// 20 Apr 99 additional error tests added.
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
# pragma warning(disable: 4786) // identifier truncated in debug info
# pragma warning(disable: 4710) // function not inlined
# pragma warning(disable: 4711) // function selected for automatic inline expansion
# pragma warning(disable: 4514) // unreferenced inline removed
#if (BOOST_MSVC >= 1310)
# pragma warning(disable: 4675) // resolved overload found with Koenig lookup
#endif
#endif
#ifdef __BORLANDC__
# pragma warn -8092 // template argument passed to 'find' is not an iterator
#endif
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>

214
test/weak_ptr_mt_test.cpp Normal file
View File

@ -0,0 +1,214 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
//
// weak_ptr_mt_test.cpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright 2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/bind.hpp>
#include <vector>
#include <memory>
#include <stdexcept>
#include <cstdio>
#include <ctime>
#include <cstdlib>
// 'portable' thread framework
class abstract_thread
{
public:
virtual ~abstract_thread() {}
virtual void run() = 0;
};
#if !defined(BOOST_HAS_PTHREADS) && defined(BOOST_HAS_WINTHREADS)
char const * title = "Using Windows threads";
#include <windows.h>
#include <process.h>
typedef HANDLE pthread_t;
unsigned __stdcall common_thread_routine(void * pv)
{
abstract_thread * pt = static_cast<abstract_thread *>(pv);
pt->run();
delete pt;
return 0;
}
int pthread_create(pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg)
{
HANDLE h = (HANDLE)_beginthreadex(0, 0, start_routine, arg, 0, 0);
if(h != 0)
{
*thread = h;
return 0;
}
else
{
return 1; // return errno;
}
}
int pthread_join(pthread_t thread, void ** /*value_ptr*/)
{
::WaitForSingleObject(thread, INFINITE);
::CloseHandle(thread);
return 0;
}
#else
char const * title = "Using POSIX threads";
#include <pthread.h>
extern "C" void * common_thread_routine(void * pv)
{
abstract_thread * pt = static_cast<abstract_thread *>(pv);
pt->run();
delete pt;
return 0;
}
#endif
//
template<class F> class thread: public abstract_thread
{
public:
explicit thread(F f): f_(f)
{
}
void run()
{
f_();
}
private:
F f_;
};
template<class F> pthread_t createThread(F f)
{
std::auto_ptr<abstract_thread> p(new thread<F>(f));
pthread_t r;
if(pthread_create(&r, 0, common_thread_routine, p.get()) == 0)
{
p.release();
return r;
}
throw std::runtime_error("createThread failed.");
}
//
int const n = 16384;
int const k = 512; // vector size
int const m = 16; // threads
void test( std::vector< boost::shared_ptr<int> > & v )
{
using namespace std; // printf, rand
std::vector< boost::weak_ptr<int> > w( v.begin(), v.end() );
int s = 0, f = 0, r = 0;
for( int i = 0; i < n; ++i )
{
// randomly kill a pointer
v[ rand() % k ].reset();
++s;
for( int j = 0; j < k; ++j )
{
if( boost::shared_ptr<int> px = w[ j ].lock() )
{
++s;
if( rand() & 4 )
{
continue;
}
// rebind anyway with prob. 50% for add_ref_lock() against weak_release() contention
++f;
}
else
{
++r;
}
w[ j ] = v[ rand() % k ];
}
}
printf( "\n%d locks, %d forced rebinds, %d normal rebinds.", s, f, r );
}
int main()
{
using namespace std; // printf, clock_t, clock
printf("%s: %d threads, %d * %d iterations: ", title, m, n, k );
std::vector< boost::shared_ptr<int> > v( k );
for( int i = 0; i < k; ++i )
{
v[ i ].reset( new int( 0 ) );
}
clock_t t = clock();
pthread_t a[m];
for(int i = 0; i < m; ++i)
{
a[i] = createThread( boost::bind( test, v ) );
}
v.resize( 0 ); // kill original copies
for(int j = 0; j < m; ++j)
{
pthread_join( a[j], 0 );
}
t = clock() - t;
printf("\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC);
return 0;
}

View File

@ -1,20 +1,27 @@
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
#if (BOOST_MSVC >= 1310)
#pragma warning(disable: 4675) // resolved overload found with Koenig lookup
#endif
#endif
//
// weak_ptr_test.cpp
//
// Copyright (c) 2002, 2003 Peter Dimov
// Copyright (c) 2002-2005 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the 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/lightweight_test.hpp>
@ -493,7 +500,7 @@ void test()
namespace n_assignment
{
template<class T> void copy_assignment(boost::shared_ptr<T> sp)
template<class T> void copy_assignment(boost::shared_ptr<T> & sp)
{
BOOST_TEST(sp.unique());
@ -604,7 +611,7 @@ void conversion_assignment()
}
}
template<class T, class U> void shared_ptr_assignment(boost::shared_ptr<U> sp, T * = 0)
template<class T, class U> void shared_ptr_assignment(boost::shared_ptr<U> & sp, T * = 0)
{
BOOST_TEST(sp.unique());
@ -637,18 +644,62 @@ template<class T, class U> void shared_ptr_assignment(boost::shared_ptr<U> sp, T
void test()
{
copy_assignment(boost::shared_ptr<int>(new int));
copy_assignment(boost::shared_ptr<X>(new X));
copy_assignment(boost::shared_ptr<void>(new int));
copy_assignment(create_incomplete());
{
boost::shared_ptr<int> p( new int );
copy_assignment( p );
}
{
boost::shared_ptr<X> p( new X );
copy_assignment( p );
}
{
boost::shared_ptr<void> p( new int );
copy_assignment( p );
}
{
boost::shared_ptr<incomplete> p = create_incomplete();
copy_assignment( p );
}
conversion_assignment();
shared_ptr_assignment<int>(boost::shared_ptr<int>(new int));
shared_ptr_assignment<void>(boost::shared_ptr<int>(new int));
shared_ptr_assignment<X>(boost::shared_ptr<X>(new X));
shared_ptr_assignment<void>(boost::shared_ptr<X>(new X));
shared_ptr_assignment<void>(boost::shared_ptr<void>(new int));
shared_ptr_assignment<incomplete>(create_incomplete());
shared_ptr_assignment<void>(create_incomplete());
{
boost::shared_ptr<int> p( new int );
shared_ptr_assignment<int>( p );
}
{
boost::shared_ptr<int> p( new int );
shared_ptr_assignment<void>( p );
}
{
boost::shared_ptr<X> p( new X );
shared_ptr_assignment<X>( p );
}
{
boost::shared_ptr<X> p( new X );
shared_ptr_assignment<void>( p );
}
{
boost::shared_ptr<void> p( new int );
shared_ptr_assignment<void>( p );
}
{
boost::shared_ptr<incomplete> p = create_incomplete();
shared_ptr_assignment<incomplete>( p );
}
{
boost::shared_ptr<incomplete> p = create_incomplete();
shared_ptr_assignment<void>( p );
}
}
} // namespace n_assignment
@ -656,7 +707,7 @@ void test()
namespace n_reset
{
template<class T, class U> void test2(boost::shared_ptr<U> sp, T * = 0)
template<class T, class U> void test2( boost::shared_ptr<U> & sp, T * = 0 )
{
BOOST_TEST(sp.unique());
@ -690,13 +741,40 @@ template<class T, class U> void test2(boost::shared_ptr<U> sp, T * = 0)
void test()
{
test2<int>(boost::shared_ptr<int>(new int));
test2<void>(boost::shared_ptr<int>(new int));
test2<X>(boost::shared_ptr<X>(new X));
test2<void>(boost::shared_ptr<X>(new X));
test2<void>(boost::shared_ptr<void>(new int));
test2<incomplete>(create_incomplete());
test2<void>(create_incomplete());
{
boost::shared_ptr<int> p( new int );
test2<int>( p );
}
{
boost::shared_ptr<int> p( new int );
test2<void>( p );
}
{
boost::shared_ptr<X> p( new X );
test2<X>( p );
}
{
boost::shared_ptr<X> p( new X );
test2<void>( p );
}
{
boost::shared_ptr<void> p( new int );
test2<void>( p );
}
{
boost::shared_ptr<incomplete> p = create_incomplete();
test2<incomplete>( p );
}
{
boost::shared_ptr<incomplete> p = create_incomplete();
test2<void>( p );
}
}
} // namespace n_reset

View File

@ -0,0 +1,85 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
//
// weak_ptr_timing_test.cpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright 2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <vector>
#include <cstdio>
#include <ctime>
#include <cstdlib>
//
int const n = 29000;
int const k = 2048;
void test( std::vector< boost::shared_ptr<int> > & v )
{
using namespace std; // printf, rand
std::vector< boost::weak_ptr<int> > w( v.begin(), v.end() );
int s = 0, r = 0;
for( int i = 0; i < n; ++i )
{
// randomly kill a pointer
v[ rand() % k ].reset();
for( int j = 0; j < k; ++j )
{
if( boost::shared_ptr<int> px = w[ j ].lock() )
{
++s;
}
else
{
++r;
w[ j ] = v[ rand() % k ];
}
}
}
printf( "\n%d locks, %d rebinds.", s, r );
}
int main()
{
using namespace std; // printf, clock_t, clock
std::vector< boost::shared_ptr<int> > v( k );
for( int i = 0; i < k; ++i )
{
v[ i ].reset( new int( 0 ) );
}
clock_t t = clock();
test( v );
t = clock() - t;
printf( "\n\n%.3f seconds.\n", static_cast<double>( t ) / CLOCKS_PER_SEC );
return 0;
}

View File

@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">weak_ptr
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle">weak_ptr
class template</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
@ -145,9 +145,8 @@ template&lt;class Y&gt; weak_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp;
<h3><a name="use_count">use_count</a></h3>
<pre>long use_count() const;</pre>
<blockquote>
<p><b>Returns:</b> if <STRONG>*this</STRONG> is <EM>empty</EM>, an unspecified
nonnegative value; otherwise, the number of <b>shared_ptr</b> objects that <EM>share
ownership</EM> with <STRONG>*this</STRONG>.</p>
<p><b>Returns:</b> 0 if <STRONG>*this</STRONG> is <EM>empty</EM>; otherwise, the
number of <b>shared_ptr</b> objects that <EM>share ownership</EM> with <STRONG>*this</STRONG>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
for debugging and testing purposes, not for production code.</P>
@ -189,7 +188,7 @@ template&lt;class Y&gt; weak_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp;
<LI>
under the equivalence relation defined by <STRONG>operator&lt;</STRONG>, <code>!(a
&lt; b) &amp;&amp; !(b &lt; a)</code>, two <STRONG>weak_ptr</STRONG> instances
are equivalent if and only if they <EM>share ownership</EM>.</LI></UL>
are equivalent if and only if they <EM>share ownership</EM> or are both <EM>empty</EM>.</LI></UL>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Allows <STRONG>weak_ptr</STRONG> objects to be used as keys in
associative containers.</P>
@ -236,7 +235,7 @@ public:
<hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002, 2003 Peter Dimov. Permission to copy, use, modify, sell and
Copyright 2002-2005 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>