Compare commits

...

146 Commits

Author SHA1 Message Date
Beman Dawes
40f6214c42 1.36.0
[SVN r48100]
2008-08-12 12:44:50 +00:00
Peter Dimov
6ba78f76f6 Merge 47736 from trunk (untabify).
[SVN r47739]
2008-07-23 20:47:47 +00:00
Peter Dimov
556b9fe563 Merge 47357 (atomic access N2674 edits) from trunk to release.
[SVN r47358]
2008-07-12 16:18:05 +00:00
Peter Dimov
991b02b03e Whitespace fix.
[SVN r47356]
2008-07-12 15:16:31 +00:00
Peter Dimov
31d0c48f18 Merged 45224, 45225 from trunk to release.
[SVN r47355]
2008-07-12 14:47:13 +00:00
Peter Dimov
1b49f08cb8 Merged 44686 from trunk to release.
[SVN r47350]
2008-07-12 12:21:19 +00:00
Peter Dimov
034c12d244 Merged 44636, 44640, 45094 (atomic access) from trunk to release.
[SVN r47349]
2008-07-12 11:57:45 +00:00
Peter Dimov
f884c53bd6 Updated spinlock_pool.hpp from trunk HEAD; takes care of 45069.
[SVN r47346]
2008-07-12 11:41:20 +00:00
Peter Dimov
07b4c17980 Merged 44979, 45068, 45085, 45089, 45177, 45194, 45346, 45422, 45545, 46055 from trunk to release
[SVN r47345]
2008-07-12 11:37:16 +00:00
Peter Dimov
1bc4f16ff8 Update esft_regtest.cpp to trunk HEAD; takes care of 43829, 43856, 44775.
[SVN r47342]
2008-07-12 10:45:56 +00:00
Peter Dimov
774a8d330c Merged 44595, 44638, 44707, 44711, 44728 from trunk to release
[SVN r47341]
2008-07-12 10:41:24 +00:00
Peter Dimov
0fd94d6d56 Updated sp_counted_base.hpp to trunk version; takes care of 44369, 44441.
[SVN r47340]
2008-07-12 10:17:08 +00:00
Peter Dimov
866590ee97 Merged 43316, 43317, 43318, 43733, 43782, 43873, 43888, 43916, 43950, 44055, 44056, 44058, 44073, 44074, 44132, 44137, 44138, 44140, 44344 from trunk to release
[SVN r47339]
2008-07-12 09:55:08 +00:00
Peter Dimov
a9cd84f43d Fix #1938 in release
[SVN r45691]
2008-05-23 20:30:15 +00:00
Peter Dimov
2fe899cdfe Disable sync use for arm and hppa.
[SVN r44440]
2008-04-15 18:57:46 +00:00
Peter Dimov
316d00c3fc Fix #1759 in release.
[SVN r44005]
2008-04-02 21:52:08 +00:00
Daniel James
4ba016d29e Merged revisions 43206,43208-43213 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix some broken links.
........
  r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Link to people pages on the website, as they've been removed from the download.
........
  r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Point links to the pages that used to be in 'more' to the site.
........
  r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix links on the home page as well.
........
  r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Generated documentation which is no longer generated.
........


[SVN r43214]
2008-02-10 16:39:38 +00:00
Beman Dawes
60ae24f4ae Pick up missing smart_ptr, utility, and type_traits files from full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41386]
2007-11-25 22:34:55 +00:00
Beman Dawes
dba6ebbb01 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes
d2194e3b24 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes
5ab6b24856 config, detail, filesystem, system, tools, at 41278.
[SVN r41316]
2007-11-23 17:03:14 +00:00
Beman Dawes
87c6b6b403 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody
c66f0aeecc This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Eric Niebler
94db735438 gcc-4.2+ moved atomicity.hpp from bits/ to ext/
[SVN r37728]
2007-05-21 01:34:43 +00:00
Peter Dimov
d889751bc0 License/copyright edits
[SVN r35957]
2006-11-09 20:24:23 +00:00
Peter Dimov
2f70e81b73 TR1 conformance fix
[SVN r35949]
2006-11-09 12:21:28 +00:00
Beman Dawes
c464a07ab1 Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
Peter Dimov
4a98c2931c Patch #1551992 (Michael Fink)
[SVN r35882]
2006-11-06 17:25:59 +00:00
Rene Rivera
ebc0af9147 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Peter Dimov
db0969d97b TR1 cyclic inclusion fix
[SVN r34512]
2006-07-12 12:31:28 +00:00
Peter Dimov
7c477960d3 Second try, revert to old Sun behavior for 5.8 and below
[SVN r34479]
2006-07-07 22:48:20 +00:00
Peter Dimov
7e5d7011e6 Attempt to fix sun-5.8 shared_ptr_delete_fail regression
[SVN r34466]
2006-07-06 12:13:25 +00:00
Peter Dimov
75cd88112c Workaround for MSVC 8.0 managed/unmanaged mismatch (reported by Loic Joly)
[SVN r33968]
2006-05-15 13:56:27 +00:00
Peter Dimov
6e120f4bf1 Fix VC6 codegen issue (Alain Cormier)
[SVN r33747]
2006-04-19 21:03:18 +00:00
Peter Dimov
7ce5b55f5c Fix issues on HP-UX (ILP32 model)
[SVN r33464]
2006-03-24 00:38:22 +00:00
nobody
f3e94d8ca0 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
Peter Dimov
c36e023162 Documented the allocator support
[SVN r33393]
2006-03-19 19:52:00 +00:00
Peter Dimov
00f744bf1e Minor rewording.
[SVN r33367]
2006-03-18 14:58:20 +00:00
Peter Dimov
24d1e6f8dd Added 'm'(*pw) inputs (thanks to Howard Hinnant)
[SVN r33364]
2006-03-18 01:48:21 +00:00
Peter Dimov
ae0a48d544 Removed erroneous // never throws annotations (reported by Scott Meyers)
[SVN r33241]
2006-03-06 23:06:10 +00:00
Peter Dimov
e427716dc2 Fully qualified detail:: to work around a subtle VC 7.1 problem.
[SVN r32994]
2006-02-18 19:17:33 +00:00
Peter Dimov
8c256502cc Added a test for rvalue auto_ptrs
[SVN r32327]
2006-01-15 13:55:37 +00:00
Peter Dimov
a86b2f7fbf Rvalue auto_ptr support, technique by Dave Abrahams
[SVN r32326]
2006-01-15 13:54:53 +00:00
Peter Dimov
a196f39cd0 Added documentation for pointer_to_other.hpp.
[SVN r31941]
2005-12-06 23:17:32 +00:00
Peter Dimov
90b5a3736a Pointer utilities added (proposed by Ion Gaztañaga)
[SVN r31932]
2005-12-06 13:26:13 +00:00
Peter Dimov
2d25f8f036 Qualified ptrdiff_t with std:: (fixes a failure on CW 9.4)
[SVN r31790]
2005-11-27 17:16:30 +00:00
Peter Dimov
3771707bb7 Added a test for the custom allocator constructor/reset.
[SVN r31624]
2005-11-11 21:07:18 +00:00
Peter Dimov
239bb6d966 #include reorderings for Boost.TR1
[SVN r31623]
2005-11-11 21:06:08 +00:00
Peter Dimov
25ca855127 shared_ptr( p, d, a ) added.
[SVN r31613]
2005-11-09 20:05:42 +00:00
Peter Dimov
0127c06692 Added a note that it's not necessary to initialize _internal_weak_this.
[SVN r31566]
2005-11-05 14:40:29 +00:00
Peter Dimov
9edd3beebc Added a note that it's not necessary to initialize _internal_weak_this.
[SVN r31565]
2005-11-05 14:33:42 +00:00
Peter Dimov
92a027fbeb Minor warning fix for SGI MIPSPro (Kevin Wheatley)
[SVN r31113]
2005-09-25 22:00:31 +00:00
Peter Dimov
7880720bc1 Made the Boost logo link to the home page
[SVN r31112]
2005-09-25 21:54:19 +00:00
Peter Dimov
235994873f Documented conversion to 'unspecified bool'
[SVN r31111]
2005-09-25 21:49:08 +00:00
Peter Dimov
7bfddbccf6 Comparison operators against a raw pointer now accept different types
[SVN r31110]
2005-09-25 21:27:00 +00:00
Douglas Gregor
c6a4e93a05 Qualify detail references
[SVN r30824]
2005-09-06 03:28:01 +00:00
John Maddock
ff7e027648 Large patch from Ulrich Eckhardt to fix support for EVC++ 4.
[SVN r30670]
2005-08-25 16:27:28 +00:00
Peter Dimov
08f517b5b0 Switched to 'int' because 'long' is 64 bits on PPC64
[SVN r30641]
2005-08-23 21:32:42 +00:00
Peter Dimov
6b3f961542 Removed explicit register use (thanks to Howard Hinnant)
[SVN r30585]
2005-08-15 19:44:15 +00:00
Douglas Gregor
0db2a88403 Merged from 1.33.0 release
[SVN r30540]
2005-08-12 13:02:37 +00:00
Peter Dimov
afc17037de Another minor documentation fix.
[SVN r30224]
2005-07-22 23:40:53 +00:00
Peter Dimov
0cee41d47e Minor documentation fix.
[SVN r30190]
2005-07-21 00:51:38 +00:00
Peter Dimov
eb3d3464db operator< documenation fix.
[SVN r30166]
2005-07-18 20:33:59 +00:00
Peter Dimov
8d2aeea3a8 Moved warning 8027 suppression above the #includes
[SVN r29852]
2005-06-30 21:49:40 +00:00
Peter Dimov
675d09723a Lock-free implementation documented, minor changes to align with TR1
[SVN r29536]
2005-06-12 12:58:17 +00:00
Joaquín M. López Muñoz
24c23b8064 disabled asm implementation for ICC/IA64
[SVN r29166]
2005-05-24 12:11:35 +00:00
Peter Dimov
880c2e1062 Detabified.
[SVN r29039]
2005-05-18 20:10:01 +00:00
Peter Dimov
357f57d147 Added a weak_ptr timing test.
[SVN r28483]
2005-04-26 11:08:28 +00:00
Rene Rivera
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
Ben Hutchings
4e4ec29fc9 Added an implementation of sp_counted_base for g++/ia64.
[SVN r28325]
2005-04-19 17:43:48 +00:00
Rene Rivera
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
Peter Dimov
76722e125f Clear reservation for 970 (thanks to Miro Jurisic and Philip Koch)
[SVN r28060]
2005-04-08 10:39:28 +00:00
Peter Dimov
d24f6d3b97 Remove hardcoded ebx
[SVN r28017]
2005-04-06 14:12:40 +00:00
Peter Dimov
6ab6b66601 One more long -> int fix
[SVN r28016]
2005-04-06 13:40:34 +00:00
Peter Dimov
559056c856 x86-64 fixes: long -> int, lea -> mov+inc
[SVN r28015]
2005-04-06 13:34:41 +00:00
Peter Dimov
13c128f98f Enabled PPC versions
[SVN r28007]
2005-04-06 08:15:48 +00:00
Rene Rivera
3ebc9b8f0b Remove extra argument to atomic_dcrement.
[SVN r27994]
2005-04-06 00:32:09 +00:00
Peter Dimov
361a7c3fd0 PowerPC dispatch added, disabled for now.
[SVN r27988]
2005-04-05 20:39:56 +00:00
Peter Dimov
faa675ad6a PowerPC implementations added.
[SVN r27986]
2005-04-05 20:29:15 +00:00
Peter Dimov
319836fe78 Constraints fixed (again), volatile/memory clobber removed from conditional_inc
[SVN r27983]
2005-04-05 16:04:36 +00:00
Peter Dimov
d0656015ad Fixed 'eax' to '%eax' in clobber; enabled gcc/x86 version
[SVN r27965]
2005-04-04 22:43:03 +00:00
Peter Dimov
f1a9148a43 Constraints fixed for g++ 3.4, atomic_increment added
[SVN r27958]
2005-04-04 19:36:18 +00:00
Peter Dimov
1942b64751 weak_ptr_mt_test.cpp added.
[SVN r27938]
2005-04-02 19:35:58 +00:00
Peter Dimov
a0eb5daf75 Mark eax as earlyclobber
[SVN r27937]
2005-04-02 18:56:38 +00:00
Peter Dimov
6046a099ba Added an implementation of sp_counted_base for g++/x86
[SVN r27933]
2005-04-02 17:14:26 +00:00
Peter Dimov
e0ee037e2d Spinlocks removed.
[SVN r27932]
2005-04-02 13:12:28 +00:00
Peter Dimov
13657c8bda lw_mutex_test added.
[SVN r27931]
2005-04-02 12:51:17 +00:00
Peter Dimov
52587aaa05 Fixed shared_ptr_delete_fail failure on g++ 3.3 and below
[SVN r27930]
2005-04-02 12:00:14 +00:00
Peter Dimov
0669d41076 Atomics are in namespace __gnu_cxx for g++ 3.4+
[SVN r27929]
2005-04-02 11:37:53 +00:00
Peter Dimov
8f2beee8e9 Link fixed.
[SVN r27906]
2005-04-01 19:33:00 +00:00
Peter Dimov
3adfc7842c Kill *_linux variants of atomic_count and lightweight_mutex.
[SVN r27889]
2005-03-30 22:52:54 +00:00
Peter Dimov
613e684b30 shared_ptr_delete_fail.cpp added (reported by Dan Bikel)
[SVN r27888]
2005-03-30 22:06:25 +00:00
Peter Dimov
bfc0225cda Switched to atomic_count
[SVN r27811]
2005-03-24 21:55:24 +00:00
Peter Dimov
a67e505cf5 Made use of detail/interlocked.hpp
[SVN r27810]
2005-03-24 21:29:29 +00:00
Peter Dimov
adec862262 atomic_count_test.cpp added.
[SVN r27746]
2005-03-20 15:40:30 +00:00
Peter Dimov
c6bf857f8b Made the pthread mutex mutable
[SVN r27740]
2005-03-18 21:27:22 +00:00
Peter Dimov
14024e2598 Add a comment thanking Ben Hutchings for the #w+(#s!=0) formulation
[SVN r27735]
2005-03-18 13:04:43 +00:00
Peter Dimov
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
Peter Dimov
09a0ba8c75 sp_counted_impl_p added for the pointer constructor
[SVN r27727]
2005-03-17 23:30:47 +00:00
Peter Dimov
b0eb65b433 Refactored sp_counted_impl.hpp out of shared_count.hpp
[SVN r27726]
2005-03-17 23:05:26 +00:00
Peter Dimov
c830315dff Refactored shared_count.hpp into bad_weak_ptr.hpp, sp_counted_base.hpp
[SVN r27725]
2005-03-17 22:45:11 +00:00
Peter Dimov
b07447aa6e BCB 6.4 still needs option -pc (reported by Pavel Vozenilek)
[SVN r27672]
2005-03-15 16:02:01 +00:00
Peter Dimov
42a739b357 Fixed nonportable elision assumption.
[SVN r27093]
2005-02-04 16:39:44 +00:00
Peter Dimov
7d59d29ad1 HP aCC fix for get_deleter (Jaroslav Gresula)
[SVN r27092]
2005-02-04 16:28:50 +00:00
Peter Dimov
5616a1a872 Added note on BOOST_MEM_FN_ENABLE_STDCALL.
[SVN r26687]
2005-01-13 13:45:59 +00:00
Aleksey Gurtovoy
e5c1e12a66 merge RC_1_32_0 fixes
[SVN r26333]
2004-11-28 04:44:21 +00:00
Peter Dimov
8f317492ee Outdated comment removed (Jonathan Wakely)
[SVN r26272]
2004-11-22 12:32:35 +00:00
Aleksey Gurtovoy
c81be1e2e7 c++boost.gif -> boost.png replacement
[SVN r25573]
2004-10-05 15:45:52 +00:00
John Maddock
1bc58ea861 Updated to use the BSL (using permissions supplied in more/blanket-permission.txt)
[SVN r24804]
2004-08-29 10:29:46 +00:00
Peter Dimov
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
Douglas Gregor
ef51f6a1de License update
[SVN r24598]
2004-08-19 15:23:47 +00:00
Douglas Gregor
6b00a55542 License updates
[SVN r24597]
2004-08-19 15:19:17 +00:00
John Maddock
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
John Maddock
c7abff0099 Updated Beman Dawes' licence statement to use the new prefered form of words.
[SVN r24370]
2004-08-10 10:34:20 +00:00
Douglas Gregor
cb6cb636f7 Converted to Boost Software License, Version 1.0
[SVN r24055]
2004-07-26 00:32:12 +00:00
John Maddock
366d2666d4 Licence update
[SVN r24031]
2004-07-25 12:01:00 +00:00
Peter Dimov
9c67a59d43 Fixed lwm_gcc, had the same bug as atomic_count_gcc (Tyson Whitehead)
[SVN r23367]
2004-07-06 10:52:06 +00:00
Peter Dimov
7361e476b8 Fixed operator--
[SVN r23210]
2004-06-27 15:40:29 +00:00
Peter Dimov
e1bd18f6a6 Made value_ mutable to enable operator long() const to compile
[SVN r23208]
2004-06-27 15:09:46 +00:00
Vladimir Prus
1346982b80 Fix a typo
[SVN r23077]
2004-06-10 12:31:20 +00:00
Peter Dimov
c48f05dcb4 enable_shared_from_this is now const-tolerant.
[SVN r22298]
2004-02-16 18:50:07 +00:00
Peter Dimov
53cc52127b Self-assignment optimization
[SVN r22233]
2004-02-10 23:17:12 +00:00
Beman Dawes
7fb399b3bb index.htm renamed index.html
[SVN r21231]
2003-12-11 23:31:15 +00:00
Peter Dimov
93d69af60a _MSC_VER use clarified.
[SVN r20992]
2003-11-28 15:35:21 +00:00
Peter Dimov
09c8685181 Fixed a VC7 'regression' (pointers to volatile cannot be deleted)
[SVN r20977]
2003-11-27 16:58:23 +00:00
Dave Abrahams
15d6b2aace CWPro8 workaround
[SVN r20323]
2003-10-09 14:14:26 +00:00
Dave Abrahams
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
Peter Dimov
26a93f224e Changed index.htm to redirect to smart_ptr.htm
[SVN r20239]
2003-10-01 11:13:04 +00:00
Peter Dimov
96f572b19b Switched unspecified_bool_type to data member pointer.
[SVN r20238]
2003-10-01 11:12:15 +00:00
Vladimir Prus
d6c4633e89 Add V2 Jamfile
[SVN r20223]
2003-09-30 07:42:34 +00:00
Beman Dawes
106a6d58d4 Change license message to reference Boost Software License
[SVN r20038]
2003-09-12 17:09:29 +00:00
Dave Abrahams
debd953d8f Use the import rule
[SVN r19968]
2003-09-08 17:38:49 +00:00
Peter Dimov
f2c5439644 'volatile' fixes.
[SVN r19961]
2003-09-08 12:26:02 +00:00
Peter Dimov
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
Peter Dimov
2d4eb92401 get_deleter fix for EDG 2.38
[SVN r19148]
2003-07-16 11:54:49 +00:00
Peter Dimov
192970b3b8 const_pointer_cast added.
[SVN r19147]
2003-07-16 11:51:12 +00:00
Peter Dimov
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
Peter Dimov
794de98cd1 #include <boost/config.hpp> added.
[SVN r19065]
2003-07-11 17:03:56 +00:00
Peter Dimov
dcdbaf1e57 A binary compatible 'null' lightweight_mutex for Win32 added.
[SVN r18916]
2003-07-02 11:54:40 +00:00
Peter Dimov
6dbec7621d Detect the VC6 STL, not VC6 itself (for Intel)
[SVN r18837]
2003-06-18 16:03:09 +00:00
Peter Dimov
889cb6bee6 -Wundef fixes.
[SVN r18788]
2003-06-12 17:09:24 +00:00
Peter Dimov
11cddbbb45 Minor fix, scoped_ptr in the intro should've been shared_ptr.
[SVN r18745]
2003-06-09 18:25:41 +00:00
Peter Dimov
77c629b6e4 smart_ptr.hpp now includes all smart pointer headers for convenience.
[SVN r18588]
2003-05-28 13:51:35 +00:00
Peter Dimov
d091ee85c0 Turns out Sun CC doesn't like operator int().
[SVN r18512]
2003-05-23 13:46:07 +00:00
Peter Dimov
bc00d5fa1a Fixed bool conversions for Sun 5.3
[SVN r18419]
2003-05-16 12:11:17 +00:00
Peter Dimov
e760759414 Fixed a copy/assignment issue.
[SVN r18122]
2003-03-28 12:27:55 +00:00
126 changed files with 8701 additions and 1719 deletions

View File

@@ -1,105 +1,88 @@
<!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>Smart Pointer Changes</title>
</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
Pointer Changes</h1>
<p>The February 2002 change to the Boost smart pointers introduced a number
of changes. Since the previous version of the smart pointers was in use for
a long time, it's useful to have a detailed list of what changed from a library
user's point of view.</p>
<p>Note that for compilers that don't support member templates well enough,
a separate implementation is used that lacks many of the new features and is
more like the old version.</p>
<h2>Features Requiring Code Changes to Take Advantage</h2>
<ul>
<li>The smart pointer class templates now each have their own header file.
For compatibility, the
<a href="../../boost/smart_ptr.hpp">&lt;boost/smart_ptr.hpp&gt;</a>
header now includes the headers for the four classic smart pointer class templates.</li>
<li>The <b>weak_ptr</b> template was added.</li>
<li>The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that the pointed-to object's
destructor must be visible when instantiating the <b>shared_ptr</b> destructor.
This makes it easier to have shared_ptr members in classes without explicit destructors.</li>
<li>A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.</li>
<li><b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b> and
<b>dynamic_cast</b> do for pointers.</li>
<li>The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
Calling <b>reset</b> with a pointer to the object that's already owned by the
<b>shared_ptr</b> results in undefined behavior
(an assertion, or eventually a double-delete if assertions are off).</li>
<li>The <b>BOOST_SMART_PTR_CONVERSION</b> feature has been removed.</li>
<li><b>shared_ptr&lt;void&gt;</b> is now allowed.</li>
</ul>
<h2>Features That Improve Robustness</h2>
<ul>
<li>The manipulation of use counts is now <a name="threadsafe">thread safe</a> on Windows, Linux, and platforms
that support pthreads. See the
<a href="../../boost/detail/atomic_count.hpp">&lt;boost/detail/atomic_count.hpp&gt;</a>
file for details</li>
<li>The new shared_ptr will always delete the object using the pointer it was originally constructed with.
This prevents subtle problems that could happen if the last <b>shared_ptr</b> was a pointer to a sub-object
of a class that did not have a virtual destructor.</li>
</ul>
<h2>Implementation Details</h2>
<ul>
<li>Some bugs in the assignment operator implementations and in <b>reset</b>
have been fixed by using the &quot;copy and swap&quot; idiom.</li>
<li>Assertions have been added to check preconditions of various functions;
however, since these use the new
<a href="../../boost/assert.hpp">&lt;boost/assert.hpp&gt;</a>
header, the assertions are disabled by default.</li>
<li>The partial specialization of <b>std::less</b> has been replaced by <b>operator&lt;</b>
overloads which accomplish the same thing without relying on undefined behavior.</li>
<li>The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>, which
has many of the same advantages for generic programming but does not violate the C++ standard.</li>
</ul>
<hr>
<p>Revised 1 February 2002</p>
<p>Copyright 2002 Darin Adler.
Permission to copy, use,
modify, sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided &quot;as is&quot;
without express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
</body>
<head>
<title>Smart Pointer Changes</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>Smart Pointer Changes</h1>
<p>The February 2002 change to the Boost smart pointers introduced a number of
changes. Since the previous version of the smart pointers was in use for a long
time, it's useful to have a detailed list of what changed from a library user's
point of view.</p>
<p>Note that for compilers that don't support member templates well enough, a
separate implementation is used that lacks many of the new features and is more
like the old version.</p>
<h2>Features Requiring Code Changes to Take Advantage</h2>
<ul>
<li>
The smart pointer class templates now each have their own header file. For
compatibility, the <a href="../../boost/smart_ptr.hpp">&lt;boost/smart_ptr.hpp&gt;</a>
header now includes the headers for the four classic smart pointer class
templates.
<li>
The <b>weak_ptr</b>
template was added.
<li>
The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that
the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
destructor. This makes it easier to have shared_ptr members in classes without
explicit destructors.
<li>
A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
<li>
<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
and <b>dynamic_cast</b>
do for pointers.
<li>
The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
results in undefined behavior (an assertion, or eventually a double-delete if
assertions are off).
<li>
The <b>BOOST_SMART_PTR_CONVERSION</b>
feature has been removed.
<li>
<b>shared_ptr&lt;void&gt;</b> is now allowed.</li>
</ul>
<h2>Features That Improve Robustness</h2>
<ul>
<li>
The manipulation of use counts is now <a name="threadsafe">thread safe</a> on
Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp">
&lt;boost/detail/atomic_count.hpp&gt;</a>
file for details
<li>
The new shared_ptr will always delete the object using the pointer it was
originally constructed with. This prevents subtle problems that could happen if
the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did
not have a virtual destructor.</li>
</ul>
<h2>Implementation Details</h2>
<ul>
<li>
Some bugs in the assignment operator implementations and in <b>reset</b>
have been fixed by using the "copy and swap" idiom.
<li>
Assertions have been added to check preconditions of various functions;
however, since these use the new <a href="../../boost/assert.hpp">&lt;boost/assert.hpp&gt;</a>
header, the assertions are disabled by default.
<li>
The partial specialization of <b>std::less</b> has been replaced by <b>operator&lt;</b>
overloads which accomplish the same thing without relying on undefined
behavior.
<li>
The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>,
which has many of the same advantages for generic programming but does not
violate the C++ standard.</li>
</ul>
<hr>
<p>Revised 1 February 2002</p>
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@@ -7,10 +7,9 @@
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
<table border="0" width="100%">
<tr>
<td width="277">
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
</td>
<td align="middle">
<td align="center">
<h1>enable_shared_from_this.hpp</h1>
</td>
</tr>
@@ -85,9 +84,8 @@ public:
</blockquote>
<p>
<br>
<small>Copyright <20> 2002, 2003 by Peter Dimov. Permission to copy, use, modify, sell
and distribute this document is granted provided this copyright notice appears
in all copies. This document is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.</small></p>
<small>Copyright <20> 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

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,17 +89,31 @@ 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( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
# include <boost/detail/atomic_count_gcc_x86.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/atomic_count_win32.hpp>
#elif defined(__GLIBCPP__)
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
# include <boost/detail/atomic_count_sync.hpp>
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# include <boost/detail/atomic_count_gcc.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_AC_USE_PTHREADS
# include <boost/detail/atomic_count_pthreads.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error

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

@@ -0,0 +1,84 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
//
// boost/detail/atomic_count_gcc_x86.hpp
//
// atomic_count for g++ on 486+/AMD64
//
// Copyright 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
void operator++()
{
__asm__
(
"lock\n\t"
"incl %0":
"+m"( value_ ): // output (%0)
: // inputs
"cc" // clobbers
);
}
long operator--()
{
return atomic_exchange_and_add( &value_, -1 ) - 1;
}
operator long() const
{
return atomic_exchange_and_add( &value_, 0 );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
mutable int value_;
private:
static int atomic_exchange_and_add( int * pw, int dv )
{
// int r = *pw;
// *pw += dv;
// return r;
int r;
__asm__ __volatile__
(
"lock\n\t"
"xadd %1, %0":
"+m"( *pw ), "=r"( r ): // outputs (%0, %1)
"1"( dv ): // inputs (%2 == %1)
"memory", "cc" // clobbers
);
return r;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED

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

@@ -0,0 +1,59 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
//
// boost/detail/atomic_count_solaris.hpp
// based on: boost/detail/atomic_count_win32.hpp
//
// Copyright (c) 2001-2005 Peter Dimov
// Copyright (c) 2006 Michael van der Westhuizen
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <atomic.h>
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( uint32_t v ): value_( v )
{
}
long operator++()
{
return atomic_inc_32_nv( &value_ );
}
long operator--()
{
return atomic_dec_32_nv( &value_ );
}
operator uint32_t() const
{
return static_cast<uint32_t const volatile &>( value_ );
}
private:
atomic_count( atomic_count const & );
atomic_count & operator=( atomic_count const & );
uint32_t value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED

View File

@@ -0,0 +1,57 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
//
// boost/detail/atomic_count_sync.hpp
//
// atomic_count for g++ 4.1+
//
// http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html
//
// Copyright 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ) : value_( v ) {}
void operator++()
{
__sync_add_and_fetch( &value_, 1 );
}
long operator--()
{
return __sync_add_and_fetch( &value_, -1 );
}
operator long() const
{
return __sync_fetch_and_add( &value_, 0 );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
mutable long value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED

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 "tr1::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,86 +1,39 @@
#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)
#if !defined(BOOST_HAS_THREADS)
# include <boost/detail/lwm_nop.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# include <boost/detail/lwm_pthreads.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>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_LWM_USE_PTHREADS
# include <boost/detail/lwm_pthreads.hpp>
# include <boost/detail/lwm_win32_cs.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error
# error Unrecognized threading platform

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
@@ -28,7 +29,7 @@ namespace detail
#ifndef BOOST_USE_WINDOWS_H
struct CRITICAL_SECTION
struct critical_section
{
struct critical_section_debug * DebugInfo;
long LockCount;
@@ -42,10 +43,14 @@ struct CRITICAL_SECTION
#endif
};
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
#else
typedef ::CRITICAL_SECTION critical_section;
#endif // #ifndef BOOST_USE_WINDOWS_H
@@ -53,7 +58,7 @@ class lightweight_mutex
{
private:
CRITICAL_SECTION cs_;
critical_section cs_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);

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,47 @@
#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)
//
#include <boost/config.hpp>
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
#endif
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/detail/lightweight_mutex.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#include <boost/detail/quick_allocator.hpp>
#endif
#include <memory> // std::auto_ptr, std::allocator
#include <functional> // std::less
#include <exception> // std::exception
#include <new> // std::bad_alloc
#include <typeinfo> // std::type_info in get_deleter
#include <cstddef> // std::size_t
#ifdef __BORLANDC__
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
# pragma warn -8027 // Functions containing try are not expanded inline
#endif
#include <boost/config.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/detail/bad_weak_ptr.hpp>
#include <boost/detail/sp_counted_base.hpp>
#include <boost/detail/sp_counted_impl.hpp>
// In order to avoid circular dependencies with Boost.TR1
// we make sure that our include of <memory> doesn't try to
// pull in the TR1 headers: that's why we use this header
// rather than including <memory> directly:
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
#include <functional> // std::less
#include <new> // std::bad_alloc
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;
@@ -303,6 +49,8 @@ int const weak_count_id = 0x298C38A4;
#endif
struct sp_nothrow_tag {};
class weak_count;
class shared_count
@@ -326,7 +74,7 @@ public:
{
}
template<class P, class D> shared_count(P p, D d): pi_(0)
template<class Y> explicit shared_count( Y * p ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
@@ -335,7 +83,44 @@ public:
try
{
pi_ = new sp_counted_base_impl<P, D>(p, d);
pi_ = new sp_counted_impl_p<Y>( p );
}
catch(...)
{
boost::checked_delete( p );
throw;
}
#else
pi_ = new sp_counted_impl_p<Y>( p );
if( pi_ == 0 )
{
boost::checked_delete( p );
boost::throw_exception( std::bad_alloc() );
}
#endif
}
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
#else
template<class P, class D> shared_count( P p, D d ): pi_(0)
#endif
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
typedef Y* P;
#endif
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = new sp_counted_impl_pd<P, D>(p, d);
}
catch(...)
{
@@ -345,7 +130,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)
{
@@ -353,6 +138,52 @@ public:
boost::throw_exception(std::bad_alloc());
}
#endif
}
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
typedef sp_counted_impl_pda<P, D, A> impl_type;
typedef typename A::template rebind< impl_type >::other A2;
A2 a2( a );
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
}
catch(...)
{
d( p );
if( pi_ != 0 )
{
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
}
throw;
}
#else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
if( pi_ != 0 )
{
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
}
else
{
d( p );
boost::throw_exception( std::bad_alloc() );
}
#endif
}
@@ -361,11 +192,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 +213,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,17 +224,22 @@ 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
shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
shared_count & operator= (shared_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if(tmp != 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;
}
@@ -416,6 +261,11 @@ public:
return use_count() == 1;
}
bool empty() const // nothrow
{
return pi_ == 0;
}
friend inline bool operator==(shared_count const & a, shared_count const & b)
{
return a.pi_ == b.pi_;
@@ -423,19 +273,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
void * get_deleter( sp_typeinfo 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
{
@@ -485,9 +331,13 @@ public:
weak_count & operator= (shared_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if(tmp != 0) tmp->weak_add_ref();
if(pi_ != 0) pi_->weak_release();
pi_ = tmp;
if( tmp != pi_ )
{
if(tmp != 0) tmp->weak_add_ref();
if(pi_ != 0) pi_->weak_release();
pi_ = tmp;
}
return *this;
}
@@ -495,9 +345,13 @@ public:
weak_count & operator= (weak_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if(tmp != 0) tmp->weak_add_ref();
if(pi_ != 0) pi_->weak_release();
pi_ = tmp;
if( tmp != pi_ )
{
if(tmp != 0) tmp->weak_add_ref();
if(pi_ != 0) pi_->weak_release();
pi_ = tmp;
}
return *this;
}
@@ -525,18 +379,25 @@ 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();
boost::throw_exception( boost::bad_weak_ptr() );
}
else
}
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if( pi_ != 0 && !pi_->add_ref_lock() )
{
boost::throw_exception(boost::bad_weak_ptr());
pi_ = 0;
}
}
@@ -546,7 +407,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,76 @@
#ifndef BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
#define BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_convertible.hpp
//
// Copyright 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x600 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
namespace boost
{
namespace detail
{
template< class Y, class T > struct sp_convertible
{
typedef char (&yes) [1];
typedef char (&no) [2];
static yes f( T* );
static no f( ... );
enum _vt { value = sizeof( f( (Y*)0 ) ) == sizeof(yes) };
};
struct sp_empty
{
};
template< bool > struct sp_enable_if_convertible_impl;
template<> struct sp_enable_if_convertible_impl<true>
{
typedef sp_empty type;
};
template<> struct sp_enable_if_convertible_impl<false>
{
};
template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
{
};
} // namespace detail
} // namespace boost
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED

View File

@@ -0,0 +1,66 @@
#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, 2006 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/config.hpp>
#if defined( BOOST_SP_DISABLE_THREADS )
# include <boost/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_USE_SPINLOCK )
# include <boost/detail/sp_counted_base_spin.hpp>
#elif defined( BOOST_SP_USE_PTHREADS )
# include <boost/detail/sp_counted_base_pt.hpp>
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/detail/sp_counted_base_nt.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
# include <boost/detail/sp_counted_base_gcc_x86.hpp>
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
# include <boost/detail/sp_counted_base_gcc_ia64.hpp>
#elif defined(__HP_aCC) && defined(__ia64)
# include <boost/detail/sp_counted_base_acc_ia64.hpp>
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
# include <boost/detail/sp_counted_base_cw_ppc.hpp>
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
# include <boost/detail/sp_counted_base_gcc_ppc.hpp>
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa )
# include <boost/detail/sp_counted_base_sync.hpp>
#elif defined(__GNUC__) && ( defined( __sparcv8 ) || defined( __sparcv9 ) )
# include <boost/detail/sp_counted_base_gcc_sparc.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>
#else
# include <boost/detail/sp_counted_base_spin.hpp>
#endif
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED

View File

@@ -0,0 +1,150 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
//
// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
//
// Copyright 2007 Baruch Zilber
// Copyright 2007 Boris Gubenko
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <machine/sys/inline.h>
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
if (1 == r)
{
_Asm_mf();
}
return r - 1;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int v = *pw;
for (;;)
{
if (0 == v)
{
return 0;
}
_Asm_mov_to_ar(_AREG_CCV,
v,
(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
if (r == v)
{
return r + 1;
}
v = r;
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_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 <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
inline void atomic_increment( register long * pw )
{
register int a;
asm
{
loop:
lwarx a, 0, pw
addi a, a, 1
stwcx. a, 0, pw
bne- loop
}
}
inline long atomic_decrement( register long * pw )
{
register int a;
asm
{
sync
loop:
lwarx a, 0, pw
addi a, a, -1
stwcx. a, 0, pw
bne- loop
isync
}
return a;
}
inline long atomic_conditional_increment( register long * pw )
{
register int a;
asm
{
loop:
lwarx a, 0, pw
cmpwi a, 0
beq store
addi a, a, 1
store:
stwcx. a, 0, pw
bne- loop
}
return a;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
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 <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
{
// int r = *pw;
// *pw += dv;
// return r;
asm
{
mov esi, [pw]
mov eax, dv
lock xadd dword ptr [esi], eax
}
}
inline void atomic_increment( int * pw )
{
//atomic_exchange_and_add( pw, 1 );
asm
{
mov esi, [pw]
lock inc dword ptr [esi]
}
}
inline int atomic_conditional_increment( int * pw )
{
// int rv = *pw;
// if( rv != 0 ) ++*pw;
// return rv;
asm
{
mov esi, [pw]
mov eax, dword ptr [esi]
L0:
test eax, eax
je L1
mov ebx, eax
inc ebx
lock cmpxchg dword ptr [esi], ebx
jne L0
L1:
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
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-2006 Peter Dimov
// Copyright 2005 Ben Hutchings
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
int tmp;
// No barrier is required here but fetchadd always has an acquire or
// release barrier associated with it. We choose release as it should be
// cheaper.
__asm__ ("fetchadd4.rel %0=%1,1" :
"=r"(tmp), "=m"(*pw) :
"m"( *pw ));
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int rv;
__asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
" cmp.eq p7,p0=1,%0 ;; \n"
"(p7) ld4.acq %0=%1 " :
"=&r"(rv), "=m"(*pw) :
"m"( *pw ) :
"p7");
return rv;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv, tmp, tmp2;
__asm__ ("0: ld4 %0=%3 ;; \n"
" cmp.eq p7,p0=0,%0 ;; \n"
"(p7) br.cond.spnt 1f \n"
" mov ar.ccv=%0 \n"
" add %1=1,%0 ;; \n"
" cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
" cmp.ne p7,p0=%0,%2 ;; \n"
"(p7) br.cond.spnt 0b \n"
" mov %0=%1 ;; \n"
"1:" :
"=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
"m"( *pw ) :
"ar.ccv", "p7");
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_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 <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
int tmp;
__asm__
(
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"addi %1, %1, 1\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b":
"=m"( *pw ), "=&b"( tmp ):
"r"( pw ), "m"( *pw ):
"cc"
);
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int rv;
__asm__ __volatile__
(
"sync\n\t"
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"addi %1, %1, -1\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b\n\t"
"isync":
"=m"( *pw ), "=&b"( rv ):
"r"( pw ), "m"( *pw ):
"memory", "cc"
);
return rv;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv;
__asm__
(
"0:\n\t"
"lwarx %1, 0, %2\n\t"
"cmpwi %1, 0\n\t"
"beq 1f\n\t"
"addi %1, %1, 1\n\t"
"1:\n\t"
"stwcx. %1, 0, %2\n\t"
"bne- 0b":
"=m"( *pw ), "=&b"( rv ):
"r"( pw ), "m"( *pw ):
"cc"
);
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
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,166 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
//
// Copyright (c) 2006 Piotr Wyderski
// Copyright (c) 2006 Tomas Puverle
// Copyright (c) 2006 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// Thanks to Michael van der Westhuizen
#include <boost/detail/sp_typeinfo.hpp>
#include <inttypes.h> // int32_t
namespace boost
{
namespace detail
{
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
{
__asm__ __volatile__( "cas %0, %2, %1"
: "+m" (*dest_), "+r" (swap_)
: "r" (compare_)
: "memory" );
return swap_;
}
inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
{
// long r = *pw;
// *pw += dv;
// return r;
for( ;; )
{
int32_t r = *pw;
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
{
return r;
}
}
}
inline void atomic_increment( int32_t * pw )
{
atomic_fetch_and_add( pw, 1 );
}
inline int32_t atomic_decrement( int32_t * pw )
{
return atomic_fetch_and_add( pw, -1 );
}
inline int32_t atomic_conditional_increment( int32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
for( ;; )
{
int32_t r = *pw;
if( r == 0 )
{
return r;
}
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
{
return r;
}
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int32_t use_count_; // #shared
int32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return const_cast< int32_t const volatile & >( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_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 <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
{
// int r = *pw;
// *pw += dv;
// return r;
int r;
__asm__ __volatile__
(
"lock\n\t"
"xadd %1, %0":
"=m"( *pw ), "=r"( r ): // outputs (%0, %1)
"m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
"memory", "cc" // clobbers
);
return r;
}
inline void atomic_increment( int * pw )
{
//atomic_exchange_and_add( pw, 1 );
__asm__
(
"lock\n\t"
"incl %0":
"=m"( *pw ): // output (%0)
"m"( *pw ): // input (%1)
"cc" // clobbers
);
}
inline int atomic_conditional_increment( int * pw )
{
// int rv = *pw;
// if( rv != 0 ) ++*pw;
// return rv;
int rv, tmp;
__asm__
(
"movl %0, %%eax\n\t"
"0:\n\t"
"test %%eax, %%eax\n\t"
"je 1f\n\t"
"movl %%eax, %2\n\t"
"incl %2\n\t"
"lock\n\t"
"cmpxchgl %2, %0\n\t"
"jne 0b\n\t"
"1:":
"=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
"m"( *pw ): // input (%3)
"cc" // clobbers
);
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
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 <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
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 <boost/detail/sp_typeinfo.hpp>
#include <pthread.h>
namespace boost
{
namespace detail
{
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
mutable pthread_mutex_t m_;
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
#if defined(__hpux) && defined(_DECTHREADS_)
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( sp_typeinfo 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,113 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
//
// detail/sp_counted_base_solaris.hpp
// based on: detail/sp_counted_base_w32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
// Copyright 2006 Michael van der Westhuizen
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <atomic.h>
namespace boost
{
namespace detail
{
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
uint32_t use_count_; // #shared
uint32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
void add_ref_copy()
{
atomic_inc_32( &use_count_ );
}
bool add_ref_lock() // true on success
{
for( ;; )
{
uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
if( tmp == 0 ) return false;
if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
}
}
void release() // nothrow
{
if( atomic_dec_32_nv( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_inc_32( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_dec_32_nv( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED

View File

@@ -0,0 +1,131 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/detail/spinlock_pool.hpp>
namespace boost
{
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
{
spinlock_pool<1>::scoped_lock lock( pw );
int r = *pw;
*pw += dv;
return r;
}
inline void atomic_increment( int * pw )
{
spinlock_pool<1>::scoped_lock lock( pw );
++*pw;
}
inline int atomic_conditional_increment( int * pw )
{
spinlock_pool<1>::scoped_lock lock( pw );
int rv = *pw;
if( rv != 0 ) ++*pw;
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
spinlock_pool<1>::scoped_lock lock( &use_count_ );
return use_count_;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED

View File

@@ -0,0 +1,155 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
//
// Copyright (c) 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/sp_typeinfo.hpp>
#include <limits.h>
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
# include <ia64intrin.h>
#endif
namespace boost
{
namespace detail
{
#if INT_MAX >= 2147483647
typedef int sp_int32_t;
#else
typedef long sp_int32_t;
#endif
inline void atomic_increment( sp_int32_t * pw )
{
__sync_fetch_and_add( pw, 1 );
}
inline sp_int32_t atomic_decrement( sp_int32_t * pw )
{
return __sync_fetch_and_add( pw, -1 );
}
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
sp_int32_t r = *pw;
for( ;; )
{
if( r == 0 )
{
return r;
}
sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
if( r2 == r )
{
return r;
}
else
{
r = r2;
}
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
sp_int32_t use_count_; // #shared
sp_int32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return const_cast< sp_int32_t const volatile & >( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED

View File

@@ -0,0 +1,130 @@
#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 <boost/detail/workaround.hpp>
#include <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
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 defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
// work around a code generation bug
long tmp2 = tmp + 1;
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
#else
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
#endif
}
}
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,231 @@
#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
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
#include <memory> // std::allocator
#endif
#include <cstddef> // std::size_t
namespace boost
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
#endif
namespace detail
{
template<class X> class sp_counted_impl_p: public sp_counted_base
{
private:
X * px_;
sp_counted_impl_p( sp_counted_impl_p const & );
sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
typedef sp_counted_impl_p<X> this_type;
public:
explicit sp_counted_impl_p( X * px ): px_( px )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px, sizeof(X), this );
#endif
}
virtual void dispose() // nothrow
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
#endif
boost::checked_delete( px_ );
}
virtual void * get_deleter( detail::sp_typeinfo 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( detail::sp_typeinfo const & ti )
{
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( 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
};
template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base
{
private:
P p_; // copy constructor must not throw
D d_; // copy constructor must not throw
A a_; // copy constructor must not throw
sp_counted_impl_pda( sp_counted_impl_pda const & );
sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
typedef sp_counted_impl_pda<P, D, A> this_type;
public:
// pre: d( p ) must not throw
sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a )
{
}
virtual void dispose() // nothrow
{
d_( p_ );
}
virtual void destroy() // nothrow
{
typedef typename A::template rebind< this_type >::other A2;
A2 a2( a_ );
this->~this_type();
a2.deallocate( this, 1 );
}
virtual void * get_deleter( detail::sp_typeinfo const & ti )
{
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
}
};
#ifdef __CODEGUARD__
# pragma option pop
#endif
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED

View File

@@ -0,0 +1,83 @@
#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_typeinfo.hpp
//
// Copyright 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined( BOOST_NO_TYPEID )
namespace boost
{
namespace detail
{
typedef void* sp_typeinfo;
template<class T> struct sp_typeid_
{
static char v_;
};
template<class T> char sp_typeid_< T >::v_;
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
{
};
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID(T) (&boost::detail::sp_typeid_<T>::v_)
#else
#include <typeinfo>
namespace boost
{
namespace detail
{
#if defined( BOOST_NO_STD_TYPEINFO )
typedef ::type_info sp_typeinfo;
#else
typedef std::type_info sp_typeinfo;
#endif
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID(T) typeid(T)
#endif
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED

View File

@@ -0,0 +1,47 @@
#ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
#define BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/spinlock.hpp
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// struct spinlock
// {
// void lock();
// bool try_lock();
// void unlock();
//
// class scoped_lock;
// };
//
// #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
//
#include <boost/config.hpp>
#if defined(__GNUC__) && defined( __arm__ )
# include <boost/detail/spinlock_gcc_arm.hpp>
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
# include <boost/detail/spinlock_sync.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/detail/spinlock_w32.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# include <boost/detail/spinlock_pt.hpp>
#elif !defined(BOOST_HAS_THREADS)
# include <boost/detail/spinlock_nt.hpp>
#else
# error Unrecognized threading platform
#endif
#endif // #ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED

View File

@@ -0,0 +1,85 @@
#ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
#define BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/yield_k.hpp>
namespace boost
{
namespace detail
{
class spinlock
{
public:
int v_;
public:
bool try_lock()
{
int r;
__asm__ __volatile__(
"swp %0, %1, [%2]":
"=&r"( r ): // outputs
"r"( 1 ), "r"( &v_ ): // inputs
"memory", "cc" );
return r == 0;
}
void lock()
{
for( unsigned k = 0; !try_lock(); ++k )
{
boost::detail::yield( k );
}
}
void unlock()
{
__asm__ __volatile__( "" ::: "memory" );
*const_cast< int volatile* >( &v_ ) = 0;
}
public:
class scoped_lock
{
private:
spinlock & sp_;
scoped_lock( scoped_lock const & );
scoped_lock & operator=( scoped_lock const & );
public:
explicit scoped_lock( spinlock & sp ): sp_( sp )
{
sp.lock();
}
~scoped_lock()
{
sp_.unlock();
}
};
};
} // namespace detail
} // namespace boost
#define BOOST_DETAIL_SPINLOCK_INIT {0}
#endif // #ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED

View File

@@ -0,0 +1,89 @@
#ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
#define BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/assert.hpp>
namespace boost
{
namespace detail
{
class spinlock
{
public:
bool locked_;
public:
inline bool try_lock()
{
if( locked_ )
{
return false;
}
else
{
locked_ = true;
return true;
}
}
inline void lock()
{
BOOST_ASSERT( !locked_ );
locked_ = true;
}
inline void unlock()
{
BOOST_ASSERT( locked_ );
locked_ = false;
}
public:
class scoped_lock
{
private:
spinlock & sp_;
scoped_lock( scoped_lock const & );
scoped_lock & operator=( scoped_lock const & );
public:
explicit scoped_lock( spinlock & sp ): sp_( sp )
{
sp.lock();
}
~scoped_lock()
{
sp_.unlock();
}
};
};
} // namespace detail
} // namespace boost
#define BOOST_DETAIL_SPINLOCK_INIT { false }
#endif // #ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED

View File

@@ -0,0 +1,87 @@
#ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
#define BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/spinlock_pool.hpp
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// spinlock_pool<0> is reserved for atomic<>, when/if it arrives
// spinlock_pool<1> is reserved for shared_ptr reference counts
// spinlock_pool<2> is reserved for shared_ptr atomic access
//
#include <boost/config.hpp>
#include <boost/detail/spinlock.hpp>
#include <cstddef>
namespace boost
{
namespace detail
{
template< int I > class spinlock_pool
{
private:
static spinlock pool_[ 41 ];
public:
static spinlock & spinlock_for( void const * pv )
{
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
return pool_[ i ];
}
class scoped_lock
{
private:
spinlock & sp_;
scoped_lock( scoped_lock const & );
scoped_lock & operator=( scoped_lock const & );
public:
explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
{
sp_.lock();
}
~scoped_lock()
{
sp_.unlock();
}
};
};
template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] =
{
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
BOOST_DETAIL_SPINLOCK_INIT
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED

View File

@@ -0,0 +1,79 @@
#ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
#define BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <pthread.h>
namespace boost
{
namespace detail
{
class spinlock
{
public:
pthread_mutex_t v_;
public:
bool try_lock()
{
return pthread_mutex_trylock( &v_ ) == 0;
}
void lock()
{
pthread_mutex_lock( &v_ );
}
void unlock()
{
pthread_mutex_unlock( &v_ );
}
public:
class scoped_lock
{
private:
spinlock & sp_;
scoped_lock( scoped_lock const & );
scoped_lock & operator=( scoped_lock const & );
public:
explicit scoped_lock( spinlock & sp ): sp_( sp )
{
sp.lock();
}
~scoped_lock()
{
sp_.unlock();
}
};
};
} // namespace detail
} // namespace boost
#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
#endif // #ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED

View File

@@ -0,0 +1,87 @@
#ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
#define BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/yield_k.hpp>
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
# include <ia64intrin.h>
#endif
namespace boost
{
namespace detail
{
class spinlock
{
public:
int v_;
public:
bool try_lock()
{
int r = __sync_lock_test_and_set( &v_, 1 );
return r == 0;
}
void lock()
{
for( unsigned k = 0; !try_lock(); ++k )
{
boost::detail::yield( k );
}
}
void unlock()
{
__sync_lock_release( &v_ );
}
public:
class scoped_lock
{
private:
spinlock & sp_;
scoped_lock( scoped_lock const & );
scoped_lock & operator=( scoped_lock const & );
public:
explicit scoped_lock( spinlock & sp ): sp_( sp )
{
sp.lock();
}
~scoped_lock()
{
sp_.unlock();
}
};
};
} // namespace detail
} // namespace boost
#define BOOST_DETAIL_SPINLOCK_INIT {0}
#endif // #ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED

View File

@@ -0,0 +1,113 @@
#ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
#define BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/interlocked.hpp>
#include <boost/detail/yield_k.hpp>
// BOOST_COMPILER_FENCE
#if defined(__INTEL_COMPILER)
#define BOOST_COMPILER_FENCE __memory_barrier();
#elif defined( _MSC_VER ) && _MSC_VER >= 1310
extern "C" void _ReadWriteBarrier();
#pragma intrinsic( _ReadWriteBarrier )
#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
#elif defined(__GNUC__)
#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
#else
#define BOOST_COMPILER_FENCE
#endif
//
namespace boost
{
namespace detail
{
class spinlock
{
public:
long v_;
public:
bool try_lock()
{
long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
BOOST_COMPILER_FENCE
return r == 0;
}
void lock()
{
for( unsigned k = 0; !try_lock(); ++k )
{
boost::detail::yield( k );
}
}
void unlock()
{
BOOST_COMPILER_FENCE
*const_cast< long volatile* >( &v_ ) = 0;
}
public:
class scoped_lock
{
private:
spinlock & sp_;
scoped_lock( scoped_lock const & );
scoped_lock & operator=( scoped_lock const & );
public:
explicit scoped_lock( spinlock & sp ): sp_( sp )
{
sp.lock();
}
~scoped_lock()
{
sp_.unlock();
}
};
};
} // namespace detail
} // namespace boost
#define BOOST_DETAIL_SPINLOCK_INIT {0}
#endif // #ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED

View File

@@ -0,0 +1,149 @@
#ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
#define BOOST_DETAIL_YIELD_K_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/yield_k.hpp
//
// Copyright (c) 2008 Peter Dimov
//
// void yield( unsigned k );
//
// Typical use:
//
// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/config.hpp>
// BOOST_SMT_PAUSE
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
extern "C" void _mm_pause();
#pragma intrinsic( _mm_pause )
#define BOOST_SMT_PAUSE _mm_pause();
#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
#endif
//
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
#endif
namespace boost
{
namespace detail
{
#if !defined( BOOST_USE_WINDOWS_H )
extern "C" void __stdcall Sleep( unsigned ms );
#endif
inline void yield( unsigned k )
{
if( k < 4 )
{
}
#if defined( BOOST_SMT_PAUSE )
else if( k < 16 )
{
BOOST_SMT_PAUSE
}
#endif
else if( k < 32 )
{
Sleep( 0 );
}
else
{
Sleep( 1 );
}
}
} // namespace detail
} // namespace boost
#elif defined( BOOST_HAS_PTHREADS )
#include <sched.h>
#include <time.h>
namespace boost
{
namespace detail
{
inline void yield( unsigned k )
{
if( k < 4 )
{
}
#if defined( BOOST_SMT_PAUSE )
else if( k < 16 )
{
BOOST_SMT_PAUSE
}
#endif
else if( k < 32 || k & 1 )
{
sched_yield();
}
else
{
// g++ -Wextra warns on {} or {0}
struct timespec rqtp = { 0, 0 };
// POSIX says that timespec has tv_sec and tv_nsec
// But it doesn't guarantee order or placement
rqtp.tv_sec = 0;
rqtp.tv_nsec = 1000;
nanosleep( &rqtp, 0 );
}
}
} // namespace detail
} // namespace boost
#else
namespace boost
{
namespace detail
{
inline void yield( unsigned )
{
}
} // namespace detail
} // namespace boost
#endif
#endif // #ifndef BOOST_DETAIL_YIELD_K_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()
@@ -40,8 +58,14 @@ public:
return p;
}
// Note: No, you don't need to initialize _internal_weak_this
//
// Please read the documentation, not the code
//
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
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->
@@ -21,9 +22,17 @@
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/detail/sp_convertible.hpp>
#include <functional> // for std::less
#include <boost/config/no_tr1/functional.hpp> // for std::less
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
#include <iosfwd> // for std::basic_ostream
#else
#include <ostream>
#endif
#endif
namespace boost
@@ -65,9 +74,19 @@ public:
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
template<class U>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
#else
intrusive_ptr( intrusive_ptr<U> const & rhs )
#endif
: p_( rhs.get() )
{
if(p_ != 0) intrusive_ptr_add_ref(p_);
if( p_ != 0 ) intrusive_ptr_add_ref( p_ );
}
#endif
@@ -104,6 +123,16 @@ public:
return *this;
}
void reset()
{
this_type().swap( *this );
}
void reset( T * rhs )
{
this_type( rhs ).swap( *this );
}
T * get() const
{
return p_;
@@ -111,21 +140,42 @@ public:
T & operator*() const
{
BOOST_ASSERT( p_ != 0 );
return *p_;
}
T * operator->() const
{
BOOST_ASSERT( p_ != 0 );
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
{
@@ -154,22 +204,22 @@ template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, in
return a.get() != b.get();
}
template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
{
return a.get() == b;
}
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
{
return a.get() != b;
}
template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
{
return a == b.get();
}
template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
{
return a != b.get();
}
@@ -207,6 +257,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());
@@ -214,7 +269,9 @@ template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U
// operator<<
#if defined(__GNUC__) && (__GNUC__ < 3)
#if !defined(BOOST_NO_IOSTREAM)
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
{
@@ -224,7 +281,10 @@ template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y>
#else
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
// in STLport's no-iostreams mode no iostream symbols can be used
#ifndef _STLP_NO_IOSTREAMS
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
using std::basic_ostream;
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
@@ -236,7 +296,11 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
return os;
}
#endif
#endif // _STLP_NO_IOSTREAMS
#endif // __GNUC__ < 3
#endif // !defined(BOOST_NO_IOSTREAM)
} // namespace boost

View File

@@ -0,0 +1,433 @@
#ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
#define BOOST_MAKE_SHARED_HPP_INCLUDED
// make_shared.hpp
//
// Copyright (c) 2007, 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://www.boost.org/libs/smart_ptr/make_shared.html
// for documentation.
#include <boost/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <cstddef>
#include <new>
namespace boost
{
namespace detail
{
template< std::size_t N, std::size_t A > struct sp_aligned_storage
{
union type
{
char data_[ N ];
typename boost::type_with_alignment< A >::type align_;
};
};
template< class T > class sp_ms_deleter
{
private:
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
bool initialized_;
storage_type storage_;
private:
void destroy()
{
if( initialized_ )
{
reinterpret_cast< T* >( storage_.data_ )->~T();
initialized_ = false;
}
}
public:
sp_ms_deleter(): initialized_( false )
{
}
~sp_ms_deleter()
{
destroy();
}
void operator()( T * )
{
destroy();
}
void * address()
{
return storage_.data_;
}
void set_initialized()
{
initialized_ = true;
}
};
template< class T > T forward( T t )
{
return t;
}
} // namespace detail
// Zero-argument versions
//
// Used even when variadic templates are available because of the new T() vs new T issue
template< class T > boost::shared_ptr< T > make_shared()
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T();
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T();
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
// Variadic templates, rvalue reference
template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( detail::forward<Args>( args )... );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( detail::forward<Args>( args )... );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
#else
// C++03 version
template< class T, class A1 >
boost::shared_ptr< T > make_shared( A1 const & a1 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A1, class A2 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1, class A2 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A1, class A2, class A3 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1, class A2, class A3 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A1, class A2, class A3, class A4 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1, class A2, class A3, class A4 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A1, class A2, class A3, class A4, class A5 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5, a6 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5, a6 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
pd->set_initialized();
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
}
#endif
} // namespace boost
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED

View File

@@ -0,0 +1,35 @@
#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
#define BOOST_MEMORY_ORDER_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/memory_order.hpp
//
// Defines enum boost::memory_order per the C++0x working draft
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
namespace boost
{
enum memory_order
{
memory_order_relaxed = 0,
memory_order_acquire = 1,
memory_order_release = 2,
memory_order_acq_rel = 3, // acquire | release
memory_order_seq_cst = 7 // acq_rel | 4
};
} // namespace boost
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED

View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_POINTER_CAST_HPP
#define BOOST_POINTER_CAST_HPP
namespace boost {
//static_pointer_cast overload for raw pointers
template<class T, class U>
inline T* static_pointer_cast(U *ptr)
{
return static_cast<T*>(ptr);
}
//dynamic_pointer_cast overload for raw pointers
template<class T, class U>
inline T* dynamic_pointer_cast(U *ptr)
{
return dynamic_cast<T*>(ptr);
}
//const_pointer_cast overload for raw pointers
template<class T, class U>
inline T* const_pointer_cast(U *ptr)
{
return const_cast<T*>(ptr);
}
//reinterpret_pointer_cast overload for raw pointers
template<class T, class U>
inline T* reinterpret_pointer_cast(U *ptr)
{
return reinterpret_cast<T*>(ptr);
}
} // namespace boost
#endif //BOOST_POINTER_CAST_HPP

View File

@@ -0,0 +1,55 @@
#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
#define BOOST_POINTER_TO_OTHER_HPP_INCLUDED
//
// pointer_to_other.hpp
//
// (C) Copyright Ion Gaztanaga 2005.
// Copyright (c) 2005 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/smart_ptr/pointer_to_other.html
//
namespace boost
{
// Defines the same pointer type (raw or smart) to another pointee type
template<class T, class U>
struct pointer_to_other;
template<class T, class U,
template<class> class Sp>
struct pointer_to_other< Sp<T>, U >
{
typedef Sp<U> type;
};
template<class T, class T2, class U,
template<class, class> class Sp>
struct pointer_to_other< Sp<T, T2>, U >
{
typedef Sp<U, T2> type;
};
template<class T, class T2, class T3, class U,
template<class, class, class> class Sp>
struct pointer_to_other< Sp<T, T2, T3>, U >
{
typedef Sp<U, T2, T3> type;
};
template<class T, class U>
struct pointer_to_other< T*, U >
{
typedef U* type;
};
} // namespace boost
#endif // #ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED

View File

@@ -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
@@ -44,6 +46,9 @@ private:
typedef scoped_array<T> this_type;
void operator==( scoped_array const& ) const;
void operator!=( scoped_array const& ) const;
public:
typedef T element_type;
@@ -83,13 +88,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
@@ -47,6 +47,9 @@ private:
typedef scoped_ptr<T> this_type;
void operator==( scoped_ptr const& ) const;
void operator!=( scoped_ptr const& ) const;
public:
typedef T element_type;
@@ -102,13 +105,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.
//
@@ -21,10 +20,13 @@
#include <boost/detail/shared_array_nmt.hpp>
#else
#include <memory> // TR1 cyclic inclusion fix
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/detail/shared_count.hpp>
#include <boost/detail/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t
#include <algorithm> // for std::swap
@@ -94,13 +96,48 @@ 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( _MANAGED )
static void unspecified_bool( this_type*** )
{
}
typedef void (*unspecified_bool_type)( this_type*** );
operator unspecified_bool_type() const // never throws
{
return px == 0? 0: unspecified_bool;
}
#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
bool operator! () const // never throws
{
return px == 0;

View File

@@ -5,12 +5,11 @@
// shared_ptr.hpp
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002, 2003 Peter Dimov
// Copyright (c) 2001-2008 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.
//
@@ -21,17 +20,35 @@
#include <boost/detail/shared_ptr_nmt.hpp>
#else
// In order to avoid circular dependencies with Boost.TR1
// we make sure that our include of <memory> doesn't try to
// pull in the TR1 headers: that's why we use this header
// rather than including <memory> directly:
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/detail/shared_count.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/detail/sp_convertible.hpp>
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
#include <boost/detail/spinlock_pool.hpp>
#include <boost/memory_order.hpp>
#endif
#include <memory> // for std::auto_ptr
#include <algorithm> // for std::swap
#include <functional> // for std::less
#include <typeinfo> // for std::bad_cast
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
#include <iosfwd> // for std::basic_ostream
#else
#include <ostream>
#endif
#endif
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
# pragma warning(push)
@@ -48,6 +65,7 @@ namespace detail
{
struct static_cast_tag {};
struct const_cast_tag {};
struct dynamic_cast_tag {};
struct polymorphic_cast_tag {};
@@ -68,19 +86,70 @@ 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 &)
#ifdef _MANAGED
// Avoid C4793, ... causes native code generation
struct sp_any_pointer
{
template<class T> sp_any_pointer( T* ) {}
};
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, sp_any_pointer, sp_any_pointer )
{
}
#else // _MANAGED
#ifdef sgi
// Turn off: the last argument of the varargs function "sp_enable_shared_from_this" is unnamed
# pragma set woff 3506
#endif
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
{
}
#ifdef sgi
# pragma reset woff 3506
#endif
#endif // _MANAGED
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
// rvalue auto_ptr support based on a technique by Dave Abrahams
template< class T, class R > struct sp_enable_if_auto_ptr
{
};
template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
{
typedef R type;
};
#endif
} // namespace detail
@@ -104,16 +173,16 @@ public:
typedef T element_type;
typedef T value_type;
typedef T * pointer;
typedef typename detail::shared_ptr_traits<T>::reference reference;
typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
shared_ptr(): px(0), pn() // never throws in 1.30+
{
}
template<class Y>
explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
{
detail::sp_enable_shared_from_this(p, p, pn);
boost::detail::sp_enable_shared_from_this( pn, p, p );
}
//
@@ -124,7 +193,14 @@ 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);
boost::detail::sp_enable_shared_from_this( pn, p, p );
}
// As above, but with allocator. A's copy constructor shall not throw.
template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
{
boost::detail::sp_enable_shared_from_this( pn, p, p );
}
// generated copy constructor, assignment, destructor are fine...
@@ -149,26 +225,55 @@ public:
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
{
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
{
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
{
if(px == 0) // need to allocate new counter -- the cast failed
if( !pn.empty() )
{
pn = detail::shared_count();
px = r.px;
}
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
shared_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
#else
shared_ptr( shared_ptr<Y> const & r )
#endif
: px( r.px ), pn( r.pn ) // never throws
{
}
// aliasing
template< class Y >
shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
{
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
{
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
{
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
{
if(px == 0) // need to allocate new counter -- the cast failed
{
pn = boost::detail::shared_count();
}
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
{
if(px == 0)
{
@@ -182,13 +287,26 @@ public:
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
{
Y * tmp = r.get();
pn = detail::shared_count(r);
detail::sp_enable_shared_from_this(tmp, tmp, pn);
pn = boost::detail::shared_count(r);
boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
}
#endif
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
template<class Ap>
shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
{
typename Ap::element_type * tmp = r.get();
pn = boost::detail::shared_count( r );
boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
}
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif // BOOST_NO_AUTO_PTR
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
template<class Y>
shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
@@ -203,12 +321,65 @@ public:
#ifndef BOOST_NO_AUTO_PTR
template<class Y>
shared_ptr & operator=(std::auto_ptr<Y> & r)
shared_ptr & operator=( std::auto_ptr<Y> & r )
{
this_type(r).swap(*this);
return *this;
}
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template<class Ap>
typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
{
this_type( r ).swap( *this );
return *this;
}
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif // BOOST_NO_AUTO_PTR
// Move support
#if defined( BOOST_HAS_RVALUE_REFS )
shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
{
pn.swap( r.pn );
r.px = 0;
}
template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
shared_ptr( shared_ptr<Y> && r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
#else
shared_ptr( shared_ptr<Y> && r )
#endif
: px( r.px ), pn() // never throws
{
pn.swap( r.pn );
r.px = 0;
}
shared_ptr & operator=( shared_ptr && r ) // never throws
{
this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
return *this;
}
template<class Y>
shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
{
this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
return *this;
}
#endif
void reset() // never throws in 1.30+
@@ -222,9 +393,19 @@ public:
this_type(p).swap(*this);
}
template<class Y, class D> void reset(Y * p, D d)
template<class Y, class D> void reset( Y * p, D d )
{
this_type(p, d).swap(*this);
this_type( p, d ).swap( *this );
}
template<class Y, class D, class A> void reset( Y * p, D d, A a )
{
this_type( p, d, a ).swap( *this );
}
template<class Y> void reset( shared_ptr<Y> const & r, T * p )
{
this_type( r, p ).swap( *this );
}
reference operator* () const // never throws
@@ -238,7 +419,7 @@ public:
BOOST_ASSERT(px != 0);
return px;
}
T * get() const // never throws
{
return px;
@@ -246,6 +427,31 @@ public:
// implicit conversion to "bool"
#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
operator bool () const
{
return px != 0;
}
#elif defined( _MANAGED )
static void unspecified_bool( this_type*** )
{
}
typedef void (*unspecified_bool_type)( this_type*** );
operator unspecified_bool_type() const // never throws
{
return px == 0? 0: unspecified_bool;
}
#elif \
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
typedef T * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
@@ -253,6 +459,17 @@ public:
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
@@ -281,9 +498,14 @@ public:
return pn < rhs.pn;
}
void * _internal_get_deleter(std::type_info const & ti) const
void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
{
return pn.get_deleter(ti);
return pn.get_deleter( ti );
}
bool _internal_equiv( shared_ptr const & r ) const
{
return px == r.px && pn == r.pn;
}
// Tasteless as this may seem, making all members public allows member templates
@@ -300,7 +522,7 @@ private:
#endif
T * px; // contained pointer
detail::shared_count pn; // reference counter
boost::detail::shared_count pn; // reference counter
}; // shared_ptr
@@ -337,29 +559,34 @@ template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::static_cast_tag());
return shared_ptr<T>(r, boost::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, boost::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());
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
}
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::static_cast_tag());
return shared_ptr<T>(r, boost::detail::static_cast_tag());
}
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::dynamic_cast_tag());
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
}
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::polymorphic_cast_tag());
return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
}
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
@@ -377,7 +604,9 @@ template<class T> inline T * get_pointer(shared_ptr<T> const & p)
// operator<<
#if defined(__GNUC__) && (__GNUC__ < 3)
#if !defined(BOOST_NO_IOSTREAM)
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
{
@@ -387,29 +616,39 @@ template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> co
#else
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
// in STLport's no-iostreams mode no iostream symbols can be used
#ifndef _STLP_NO_IOSTREAMS
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
using std::basic_ostream;
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
# else
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
# endif
# endif
{
os << p.get();
return os;
}
#endif
#endif // _STLP_NO_IOSTREAMS
// get_deleter (experimental)
#endif // __GNUC__ < 3
#if defined(__GNUC__) && (__GNUC__ < 3)
#endif // !defined(BOOST_NO_IOSTREAM)
// get_deleter
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
{
void const * q = p._internal_get_deleter(typeid(D));
void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
return const_cast<D *>(static_cast<D const *>(q));
}
@@ -417,7 +656,86 @@ template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
{
return static_cast<D *>(p._internal_get_deleter(typeid(D)));
return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
}
#endif
// atomic access
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
{
return false;
}
template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
{
boost::detail::spinlock_pool<2>::scoped_lock lock( p );
return *p;
}
template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order /*mo*/ )
{
return atomic_load( p );
}
template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
{
boost::detail::spinlock_pool<2>::scoped_lock lock( p );
p->swap( r );
}
template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
{
atomic_store( p, r ); // std::move( r )
}
template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
{
boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
sp.lock();
p->swap( r );
sp.unlock();
return r; // return std::move( r )
}
template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
{
return atomic_exchange( p, r ); // std::move( r )
}
template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w )
{
boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
sp.lock();
if( p->_internal_equiv( *v ) )
{
p->swap( w );
sp.unlock();
return true;
}
else
{
shared_ptr<T> tmp( *p );
sp.unlock();
tmp.swap( *v );
return false;
}
}
template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, memory_order /*success*/, memory_order /*failure*/ )
{
return atomic_compare_exchange( p, v, w ); // std::move( w )
}
#endif
@@ -426,7 +744,7 @@ template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
#endif
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)

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,14 +6,15 @@
//
// 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.
//
#include <memory> // boost.TR1 include order fix
#include <boost/detail/shared_count.hpp>
#include <boost/shared_ptr.hpp>
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
@@ -60,17 +61,35 @@ public:
//
template<class Y>
weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
weak_ptr( weak_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
#else
weak_ptr( weak_ptr<Y> const & r )
#endif
: pn(r.pn) // never throws
{
px = r.lock().get();
}
template<class Y>
weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
#else
weak_ptr( shared_ptr<Y> const & r )
#endif
: px( r.px ), pn( r.pn ) // never throws
{
}
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
template<class Y>
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
@@ -92,31 +111,7 @@ public:
shared_ptr<T> lock() const // never throws
{
#if defined(BOOST_HAS_THREADS)
// optimization: avoid throw overhead
if(expired())
{
return shared_ptr<element_type>();
}
try
{
return shared_ptr<element_type>(*this);
}
catch(bad_weak_ptr const &)
{
// Q: how can we get here?
// A: another thread may have invalidated r after the use_count test above.
return shared_ptr<element_type>();
}
#else
// optimization: avoid try/catch overhead when single threaded
return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
#endif
return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
}
long use_count() const // never throws
@@ -140,7 +135,7 @@ public:
pn.swap(other.pn);
}
void _internal_assign(T * px2, detail::shared_count const & pn2)
void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
{
px = px2;
pn = pn2;
@@ -163,8 +158,8 @@ private:
#endif
T * px; // contained pointer
detail::weak_count pn; // reference counter
T * px; // contained pointer
boost::detail::weak_count pn; // reference counter
}; // weak_ptr
@@ -178,12 +173,6 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
a.swap(b);
}
// deprecated, provided for backward compatibility
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
{
return r.lock();
}
} // namespace boost
#ifdef BOOST_MSVC

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>

15
index.html Normal file
View File

@@ -0,0 +1,15 @@
<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>
<!--
<09> Copyright Beman Dawes, 2001
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
-->

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">intrusive_ptr
class template</h1>
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
border="0"></A>intrusive_ptr class template</h1>
<p>
<A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
@@ -31,11 +31,11 @@
<P>The main reasons to use <STRONG>intrusive_ptr</STRONG> are:</P>
<UL>
<LI>
Some existing frameworks or OSes provide objects with embedded reference
counts;</LI>
Some existing frameworks or OSes provide objects with embedded reference
counts;
<LI>
The memory footprint of <STRONG>intrusive_ptr</STRONG> is the same as the
corresponding raw pointer;</LI>
The memory footprint of <STRONG>intrusive_ptr</STRONG>
is the same as the corresponding raw pointer;
<LI>
<STRONG>intrusive_ptr&lt;T&gt;</STRONG> can be constructed from an arbitrary
raw pointer of type <STRONG>T *</STRONG>.</LI></UL>
@@ -61,7 +61,10 @@
intrusive_ptr &amp; <A href="#assignment" >operator=</A>(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; <A href="#assignment" >operator=</A>(intrusive_ptr&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; <A href="#assignment" >operator=</A>(T * r);
intrusive_ptr &amp; <A href="#assignment" >operator=</A>(T * r);
void <a href="#reset" >reset</a>();
void <a href="#reset" >reset</a>(T * r);
T &amp; <A href="#indirection" >operator*</A>() const; // never throws
T * <A href="#indirection" >operator-&gt;</A>() const; // never throws
@@ -100,6 +103,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
@@ -124,8 +130,8 @@
<p><b>Effects:</b> <code>if(p != 0 &amp;&amp; add_ref) intrusive_ptr_add_ref(p);</code>.</p>
<p><b>Postconditions:</b> <code>get() == p</code>.</p>
</blockquote>
<pre>intrusive_ptr(intrusive_ptr const &amp; r); // never throws
template&lt;class Y&gt; intrusive_ptr(intrusive_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
<pre>intrusive_ptr(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr(intrusive_ptr&lt;Y&gt; const &amp; r);</pre>
<blockquote>
<p><b>Effects:</b> <code>if(r.get() != 0) intrusive_ptr_add_ref(r.get());</code>.</p>
<p><b>Postconditions:</b> <code>get() == r.get()</code>.</p>
@@ -136,13 +142,22 @@ template&lt;class Y&gt; intrusive_ptr(intrusive_ptr&lt;Y&gt; const &amp; r); //
<P><B>Effects:</B> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</P>
</BLOCKQUOTE>
<H3><a name="assignment">assignment</a></H3>
<pre>intrusive_ptr &amp; operator=(intrusive_ptr const &amp; r); // never throws
template&lt;class Y&gt; intrusive_ptr &amp; operator=(intrusive_ptr&lt;Y&gt; const &amp; r); // never throws
<pre>intrusive_ptr &amp; operator=(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; operator=(intrusive_ptr&lt;Y&gt; const &amp; r);
intrusive_ptr &amp; operator=(T * r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
<P><B>Returns:</B> <code>*this</code>.</P>
</BLOCKQUOTE>
<H3><a name="reset">reset</a></H3>
<pre>void reset();</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</P>
</BLOCKQUOTE>
<pre>void reset(T * r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre>
<blockquote>
@@ -193,26 +208,26 @@ intrusive_ptr &amp; operator=(T * r);</pre>
<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T&gt;
bool operator==(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws</pre>
<pre>template&lt;class T, class U&gt;
bool operator==(intrusive_ptr&lt;T&gt; const &amp; a, U * b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() == b</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T&gt;
bool operator!=(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws</pre>
<pre>template&lt;class T, class U&gt;
bool operator!=(intrusive_ptr&lt;T&gt; const &amp; a, U * b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() != b</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T&gt;
bool operator==(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws</pre>
<pre>template&lt;class T, class U&gt;
bool operator==(T * a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a == b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T&gt;
bool operator!=(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws</pre>
<pre>template&lt;class T, class U&gt;
bool operator!=(T * a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a != b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
@@ -250,6 +265,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>
@@ -268,9 +290,8 @@ intrusive_ptr &amp; operator=(T * r);</pre>
<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>
<small>Copyright <20> 2003-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

105
pointer_cast.html Normal file
View File

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

108
pointer_to_other.html Normal file
View File

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

View File

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

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86"><a name="scoped_ptr">scoped_ptr</a>
class template</h1>
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>scoped_ptr class template</h1>
<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated
object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.)
The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>,
@@ -48,6 +48,8 @@
T * <a href="#indirection">operator-&gt;</a>() const; // never throws
T * <a href="#get">get</a>() const; // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
void <a href="#swap">swap</a>(scoped_ptr &amp; b); // never throws
};
@@ -90,6 +92,10 @@
<pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
@@ -115,7 +121,7 @@ class MyClass {
int add_one() { return ++*ptr; }
};
void main()
int main()
{
boost::scoped_ptr&lt;Shoe&gt; x(new Shoe);
MyClass my_instance;
@@ -150,8 +156,8 @@ Buckle my shoe</pre>
<p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called
pimpl) idiom which avoids exposing the body (implementation) in the header
file.</p>
<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a> sample
program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a>
sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
which uses a <b>scoped_ptr&lt;&gt;</b> to an incomplete type to hide the
implementation. The instantiation of member functions which require a complete
type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a>
@@ -165,12 +171,11 @@ Buckle my shoe</pre>
given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership
is required. (supplied by Dave Abrahams)</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and
distribute this document is granted provided this copyright notice appears in
all copies. This document is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">shared_array
class template</h1>
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>shared_array class template</h1>
<p>The <b>shared_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
@@ -53,6 +53,8 @@
bool <a href="#unique">unique</a>() const; // never throws
long <a href="#use_count">use_count</a>() const; // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
void <a href="#swap">swap</a>(shared_array&lt;T&gt; &amp; b); // never throws
};
@@ -139,6 +141,10 @@
implementations of <b>shared_array</b> that do not use an explicit reference
count, it might be removed from some future version. Thus it should be used for
debugging purposes only, and not production code.</p>
<h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(shared_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
@@ -171,10 +177,9 @@ template&lt;class T&gt;
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its
suitability for any purpose.</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">shared_ptr
class template</h1>
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
border="0"></A>shared_ptr class template</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#BestPractices">Best Practices</A><br>
<A href="#Synopsis">Synopsis</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>
@@ -99,10 +106,12 @@ void bad()
<A href="#constructors" >shared_ptr</A>(); // never throws
template&lt;class Y&gt; explicit <A href="#constructors" >shared_ptr</A>(Y * p);
template&lt;class Y, class D&gt; <A href="#constructors" >shared_ptr</A>(Y * p, D d);
template&lt;class Y, class D, class A&gt; <A href="#allocator_constructor" >shared_ptr</A>(Y * p, D d, A a);
<A href="#destructor" >~shared_ptr</A>(); // never throws
<A href="#constructors" >shared_ptr</A>(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; <A href="#constructors" >shared_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;class Y&gt; <A href="#constructors" >shared_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r, T * p); // never throws
template&lt;class Y&gt; explicit <A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A>&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; explicit <A href="#constructors" >shared_ptr</A>(std::auto_ptr&lt;Y&gt; &amp; r);
@@ -113,6 +122,8 @@ void bad()
void <A href="#reset" >reset</A>(); // never throws
template&lt;class Y&gt; void <A href="#reset" >reset</A>(Y * p);
template&lt;class Y, class D&gt; void <A href="#reset" >reset</A>(Y * p, D d);
template&lt;class Y, class D, class A&gt; void <A href="#reset" >reset</A>(Y * p, D d, A a);
template&lt;class Y&gt; void <A href="#reset" >reset</A>(shared_ptr&lt;Y&gt; const &amp; r, T * p); // never throws
T &amp; <A href="#indirection" >operator*</A>() const; // never throws
T * <A href="#indirection" >operator-&gt;</A>() const; // never throws
@@ -142,6 +153,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 +165,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 +174,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 +189,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
@@ -213,18 +207,23 @@ void bad()
The current implementation uses a different mechanism, <A href="enable_shared_from_this.html">
enable_shared_from_this</A>, to solve the "<STRONG>shared_ptr</STRONG> from <STRONG>
this</STRONG>" problem.</EM><EM>]</EM></P>
<pre>template&lt;class Y, class D&gt; shared_ptr(Y * p, D d);</pre>
<a name="allocator_constructor"></a>
<pre>template&lt;class Y, class D&gt; shared_ptr(Y * p, D d);
template&lt;class Y, class D, class A&gt; shared_ptr(Y * p, D d, A a);</pre>
<blockquote>
<p><b>Requirements:</b> <B>p</B> must be convertible to <B>T *</B>. <STRONG>D</STRONG>
must be <STRONG>CopyConstructible</STRONG>. The copy constructor and destructor
of <b>D</b> must not throw. The expression <code>d(p)</code> must be
well-formed, must not invoke undefined behavior, and must not throw exceptions.
well-formed, must not invoke undefined behavior, and must not throw exceptions. <STRONG>
A</STRONG> must be an <EM>Allocator</EM>, as described in section 20.1.5 (<STRONG>Allocator
requirements</STRONG>) of the C++ Standard.
</p>
<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</STRONG> and the deleter <b>d</b>. The second constructor allocates
memory using a copy of <STRONG>a</STRONG>.</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 +241,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>
@@ -263,11 +255,17 @@ template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never
r.use_count()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r, T * p); // never throws</pre>
<blockquote>
<p><b>Effects:</b> constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with
<b>r</b> and stores <b>p</b>.</p>
<p><b>Postconditions:</b> <code>get() == p &amp;&amp; use_count() == r.use_count()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</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 +275,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 +320,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>
@@ -341,6 +333,14 @@ q = p;
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</P>
</BLOCKQUOTE>
<pre>template&lt;class Y, class D, class A&gt; void reset(Y * p, D d, A a);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d, a).swap(*this)</code>.</P>
</BLOCKQUOTE>
<pre>template&lt;class Y&gt; void reset(shared_ptr&lt;Y&gt; const &amp; r, T * p); // never throws</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>shared_ptr(r, p).swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre>
<blockquote>
@@ -373,8 +373,8 @@ q = p;
<pre>long use_count() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> the number of <b>shared_ptr</b> objects, <STRONG>*this</STRONG> included,
that <i>share ownership</i> with <b>*this</b>, or an unspecified nonnegative
value when <STRONG>*this</STRONG> is <EM>empty</EM>.</p>
that <i>share ownership</i> with <b>*this</b>, or 0 when <STRONG>*this</STRONG>
is <EM>empty</EM>.</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>
@@ -424,7 +424,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 +473,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>
@@ -507,6 +522,7 @@ q = p;
<P><B>Returns:</B> If <STRONG>*this</STRONG> <EM>owns</EM> a deleter <STRONG>d</STRONG>
of type (cv-unqualified) <STRONG>D</STRONG>, returns <code>&amp;d</code>;
otherwise returns 0.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<h2><a name="example">Example</a></h2>
<p>See <A href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a
@@ -584,11 +600,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 +646,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&amp;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,9 +710,8 @@ 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
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>
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License,
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Smart
Pointers</h1>
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
border="0"></A>Smart Pointers</h1>
<p><a href="#Introduction">Introduction</a><br>
<a href="#common_requirements">Common Requirements</a><br>
<a href="#Exception_Safety">Exception Safety</a><br>
@@ -105,7 +105,7 @@
and that is thrown only by functions which are explicitly documented as
possibly throwing <b>std::bad_alloc</b>.</p>
<h2><a name="Exception-specifications">Exception-specifications</a></h2>
<p>Exception-specifications are not used; see <a href="../../more/lib_guide.htm#Exception-specification">
<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
exception-specification rationale</a>.</p>
<p>All the smart pointer templates contain member functions which can never throw
exceptions, because they neither throw exceptions themselves nor call other
@@ -177,10 +177,9 @@
and an extensive bibliography.</p>
<hr>
<p>$Date$</p>
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its
suitability for any purpose.</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Distributed under the Boost Software License, Version 1.0. See accompanying
file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at
<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

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
@@ -21,10 +21,10 @@
mailing list and the tests which this page describes were performed to provide
a guide for current and future investigations into smart pointer implementation
strategies.</p>
<p>Thanks are due to <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>,
<p>Thanks are due to <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>,
Gavin Collings,
<a href="../../people/greg_colvin.htm">Greg Colvin</a> and
<a href="../../people/beman_dawes.html">Beman Dawes</a>
<a href="http://www.boost.org/people/greg_colvin.htm">Greg Colvin</a> and
<a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a>
for test code and trial implementations, the final version of which can be found
in .zip format <a href="smarttest.zip">here</a>.</p>
<h2>Description</h2>

View File

@@ -5,8 +5,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">Smart
Pointer Programming Techniques</h1>
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
border="0"></A>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>
<A href="#abstract">Using abstract classes for implementation hiding</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
@@ -516,6 +519,9 @@ public:
}
}
</pre>
<p>Note that you no longer need to manually initialize the <code>weak_ptr</code> member
in <code><A href="enable_shared_from_this.html">enable_shared_from_this</A></code>.
Constructing a <code>shared_ptr</code> to <code>impl</code> takes care of that.</p>
<h2><A name="handle">Using <code>shared_ptr</code> as a smart counted handle</A></h2>
<p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete">
incomplete class technique</A> described above. An example:</p>
@@ -752,9 +758,8 @@ public:
all weak pointers will automatically expire.</p>
<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>
<p><small>Copyright <20> 2003 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</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,42 +0,0 @@
# Boost.SmartPtr Library test Jamfile
#
# Copyright (c) 2003 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.
subproject libs/smart_ptr/test ;
# bring in rules for testing
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ;
# Make tests run by default.
DEPENDS all : smart_ptr ;
{
test-suite "smart_ptr"
: [ run smart_ptr_test.cpp ]
[ run shared_ptr_basic_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
[ run shared_ptr_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
[ run weak_ptr_test.cpp ]
[ run shared_from_this_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
[ run get_deleter_test.cpp ]
[ run intrusive_ptr_test.cpp ]
[ run intrusive_ptr_test.cpp ]
[ compile-fail shared_ptr_assign_fail.cpp ]
;
# this one is too slow to run unless explicitly requested, and ALL
# tests are run by default when this file is subincluded from
# boost/status, so it's guarded from that case. It will only be
# built from this directory when the targets "test" (all tests) or
# "shared_ptr_alloc_test" are requested.
if [ in-invocation-subdir ]
{
run shared_ptr_alloc_test.cpp ;
}
}

52
test/Jamfile.v2 Normal file
View File

@@ -0,0 +1,52 @@
# Boost.SmartPtr Library test Jamfile
#
# Copyright (c) 2003-2007 Peter Dimov
# Copyright (c) 2003 Dave Abrahams
#
# Distributed under the Boost Software License, Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# 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 ]
[ compile-fail shared_ptr_compare_fail.cpp ]
[ run shared_ptr_alloc2_test.cpp ]
[ run pointer_cast_test.cpp ]
[ compile pointer_to_other_test.cpp ]
[ run auto_ptr_rv_test.cpp ]
[ run shared_ptr_alias_test.cpp ]
[ run shared_ptr_rv_test.cpp ]
[ run shared_ptr_move_test.cpp ]
[ compile-fail shared_ptr_pv_fail.cpp ]
[ run sp_unary_addr_test.cpp ]
[ compile-fail scoped_ptr_eq_fail.cpp ]
[ compile-fail scoped_array_eq_fail.cpp ]
[ run esft_regtest.cpp ]
[ run yield_k_test.cpp ]
[ run yield_k_test.cpp : : : <threading>multi : yield_k_test.mt ]
[ run spinlock_test.cpp ]
[ run spinlock_try_test.cpp ]
[ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
[ run spinlock_pool_test.cpp ]
[ run make_shared_test.cpp ]
[ run sp_convertible_test.cpp ]
[ run wp_convertible_test.cpp ]
[ run ip_convertible_test.cpp ]
[ run allocate_shared_test.cpp ]
[ run sp_atomic_test.cpp ]
;
}

View File

@@ -0,0 +1,189 @@
// allocate_shared_test.cpp
//
// Copyright (c) 2007, 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/lightweight_test.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class X
{
private:
X( X const & );
X & operator=( X const & );
public:
static int instances;
int v;
explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
{
++instances;
}
~X()
{
--instances;
}
};
int X::instances = 0;
int main()
{
{
boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator<int>() );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( *pi == 0 );
}
{
boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator<int>(), 5 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( *pi == 5 );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>() );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 0 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
return boost::report_errors();
}

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();
}

111
test/auto_ptr_rv_test.cpp Normal file
View File

@@ -0,0 +1,111 @@
//
// auto_ptr_rv_test.cpp
//
// Copyright (c) 2006 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/shared_ptr.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <memory>
struct X
{
static long instances;
X()
{
++instances;
}
~X()
{
--instances;
}
static std::auto_ptr<X> create()
{
return std::auto_ptr<X>( new X );
}
private:
X( X const & );
X & operator=( X const & );
};
long X::instances = 0;
int main()
{
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr<X> p( X::create() );
BOOST_TEST( X::instances == 1 );
p = X::create();
BOOST_TEST( X::instances == 1 );
p.reset();
BOOST_TEST( X::instances == 0 );
p = X::create();
BOOST_TEST( X::instances == 1 );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr<X const> p( X::create() );
BOOST_TEST( X::instances == 1 );
p = X::create();
BOOST_TEST( X::instances == 1 );
p.reset();
BOOST_TEST( X::instances == 0 );
p = X::create();
BOOST_TEST( X::instances == 1 );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr<void> p( X::create() );
BOOST_TEST( X::instances == 1 );
p = X::create();
BOOST_TEST( X::instances == 1 );
p.reset();
BOOST_TEST( X::instances == 0 );
p = X::create();
BOOST_TEST( X::instances == 1 );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr<void const> p( X::create() );
BOOST_TEST( X::instances == 1 );
p = X::create();
BOOST_TEST( X::instances == 1 );
p.reset();
BOOST_TEST( X::instances == 0 );
p = X::create();
BOOST_TEST( X::instances == 1 );
}
BOOST_TEST( X::instances == 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>

221
test/esft_regtest.cpp Normal file
View File

@@ -0,0 +1,221 @@
//
// esft_regtest.cpp
//
// A regression test for enable_shared_from_this
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <memory>
#include <string>
class X: public boost::enable_shared_from_this< X >
{
private:
int destroyed_;
int deleted_;
int expected_;
private:
X( X const& );
X& operator=( X const& );
public:
static int instances;
public:
explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
{
++instances;
}
~X()
{
BOOST_TEST( deleted_ == expected_ );
BOOST_TEST( destroyed_ == 0 );
++destroyed_;
--instances;
}
typedef void (*deleter_type)( X* );
static void deleter( X * px )
{
++px->deleted_;
}
static void deleter2( X * px )
{
++px->deleted_;
delete px;
}
};
int X::instances = 0;
void test()
{
BOOST_TEST( X::instances == 0 );
{
X x( 0 );
BOOST_TEST( X::instances == 1 );
}
BOOST_TEST( X::instances == 0 );
{
std::auto_ptr<X> px( new X( 0 ) );
BOOST_TEST( X::instances == 1 );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr<X> px( new X( 0 ) );
BOOST_TEST( X::instances == 1 );
boost::weak_ptr<X> wp( px );
BOOST_TEST( !wp.expired() );
px.reset();
BOOST_TEST( wp.expired() );
}
BOOST_TEST( X::instances == 0 );
{
X x( 1 );
boost::shared_ptr<X> px( &x, X::deleter );
BOOST_TEST( X::instances == 1 );
X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
BOOST_TEST( pd != 0 && *pd == X::deleter );
boost::weak_ptr<X> wp( px );
BOOST_TEST( !wp.expired() );
px.reset();
BOOST_TEST( wp.expired() );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr<X> px( new X( 1 ), X::deleter2 );
BOOST_TEST( X::instances == 1 );
X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
BOOST_TEST( pd != 0 && *pd == X::deleter2 );
boost::weak_ptr<X> wp( px );
BOOST_TEST( !wp.expired() );
px.reset();
BOOST_TEST( wp.expired() );
}
BOOST_TEST( X::instances == 0 );
}
struct V: public boost::enable_shared_from_this<V>
{
virtual ~V() {}
std::string m_;
};
struct V2
{
virtual ~V2() {}
std::string m2_;
};
struct W: V2, V
{
};
void test2()
{
boost::shared_ptr<W> p( new W );
}
void test3()
{
V * p = new W;
boost::shared_ptr<void> pv( p );
BOOST_TEST( pv.get() == p );
BOOST_TEST( pv.use_count() == 1 );
}
struct null_deleter
{
void operator()( void const* ) const {}
};
void test4()
{
boost::shared_ptr<V> pv( new V );
boost::shared_ptr<V> pv2( pv.get(), null_deleter() );
BOOST_TEST( pv2.get() == pv.get() );
BOOST_TEST( pv2.use_count() == 1 );
}
void test5()
{
V v;
boost::shared_ptr<V> p1( &v, null_deleter() );
BOOST_TEST( p1.get() == &v );
BOOST_TEST( p1.use_count() == 1 );
try
{
p1->shared_from_this();
}
catch( ... )
{
BOOST_ERROR( "p1->shared_from_this() failed" );
}
p1.reset();
boost::shared_ptr<V> p2( &v, null_deleter() );
BOOST_TEST( p2.get() == &v );
BOOST_TEST( p2.use_count() == 1 );
try
{
p2->shared_from_this();
}
catch( ... )
{
BOOST_ERROR( "p2->shared_from_this() failed" );
}
}
int main()
{
test();
test2();
test3();
test4();
test5();
return boost::report_errors();
}

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 &);

View File

@@ -0,0 +1,54 @@
#include <boost/config.hpp>
// wp_convertible_test.cpp
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/lightweight_test.hpp>
#include <boost/intrusive_ptr.hpp>
//
struct W
{
};
void intrusive_ptr_add_ref( W* )
{
}
void intrusive_ptr_release( W* )
{
}
struct X: public virtual W
{
};
struct Y: public virtual W
{
};
struct Z: public X
{
};
int f( boost::intrusive_ptr<X> )
{
return 1;
}
int f( boost::intrusive_ptr<Y> )
{
return 2;
}
int main()
{
BOOST_TEST( 1 == f( boost::intrusive_ptr<Z>() ) );
return boost::report_errors();
}

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;
}

189
test/make_shared_test.cpp Normal file
View File

@@ -0,0 +1,189 @@
// make_shared_test.cpp
//
// Copyright (c) 2007, 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/lightweight_test.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class X
{
private:
X( X const & );
X & operator=( X const & );
public:
static int instances;
int v;
explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
{
++instances;
}
~X()
{
--instances;
}
};
int X::instances = 0;
int main()
{
{
boost::shared_ptr< int > pi = boost::make_shared< int >();
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( *pi == 0 );
}
{
boost::shared_ptr< int > pi = boost::make_shared< int >( 5 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( *pi == 5 );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr< X > pi = boost::make_shared< X >();
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 0 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
return boost::report_errors();
}

126
test/pointer_cast_test.cpp Normal file
View File

@@ -0,0 +1,126 @@
//
// pointer_cast_test.cpp - a test for boost/pointer_cast.hpp
//
// Copyright (c) 2005 Ion Gaztanaga
// Copyright (c) 2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/pointer_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/get_pointer.hpp>
#include <boost/detail/lightweight_test.hpp>
namespace
{
// Let's create these inheritance relationship:
//
// base base2
// | |
// derived
// |
// derived_derived
//
class base
{
public:
virtual ~base(){}
int filler [5];
};
class base2
{
public:
virtual ~base2(){}
int filler [5];
};
class derived
: public base, public base2
{
int filler [5];
};
class derived_derived
: public derived
{
int filler [5];
};
// And now some simple check functions
template <class BasePtr>
bool check_dynamic_pointer_cast(const BasePtr &ptr)
{
//Check that dynamic_pointer_cast versus dynamic_cast
return
//Correct cast with dynamic_pointer_cast
boost::get_pointer(boost::dynamic_pointer_cast<derived>(ptr)) ==
//Correct cast with dynamic_cast
dynamic_cast<derived*>(boost::get_pointer(ptr))
&&
//Incorrect cast with dynamic_pointer_cast
boost::get_pointer(boost::dynamic_pointer_cast<derived_derived>(ptr)) ==
//Incorrect cast with dynamic_cast
dynamic_cast<derived_derived*>(boost::get_pointer(ptr));
}
template <class BasePtr>
bool check_static_pointer_cast(const BasePtr &ptr)
{
return
//Cast base -> derived -> base2 using static_pointer_cast
boost::get_pointer(
boost::static_pointer_cast<base2>(
boost::static_pointer_cast<derived>(ptr))) ==
//Now the same with static_cast
static_cast<base2*>(static_cast<derived*>(boost::get_pointer(ptr)));
}
template <class BasePtr>
bool check_const_pointer_cast(const BasePtr &ptr)
{
return
//Unconst and const again using const_pointer_cast
boost::get_pointer(
boost::const_pointer_cast<const base>
(boost::const_pointer_cast<base>(ptr))) ==
//Now the same with const_cast
const_cast<const base*>(const_cast<base*>(boost::get_pointer(ptr)));
}
}
int main()
{
{
// Try casts with shared_ptr
boost::shared_ptr<base> ptr(new derived);
BOOST_TEST( check_dynamic_pointer_cast( ptr ) );
BOOST_TEST( check_static_pointer_cast( ptr ) );
BOOST_TEST( check_const_pointer_cast( ptr ) );
}
{
// Try casts with raw pointer
boost::scoped_ptr<base> ptr(new derived);
BOOST_TEST( check_dynamic_pointer_cast( ptr.get() ) );
BOOST_TEST( check_static_pointer_cast( ptr.get() ) );
BOOST_TEST( check_const_pointer_cast( ptr.get() ) );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,74 @@
//
// pointer_to_other_test.cpp - a test for boost/pointer_to_other.hpp
//
// Copyright (c) 2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/pointer_to_other.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/intrusive_ptr.hpp>
#include <memory>
template<class T, class U> void assert_same_type( T** pt = 0, U** pu = 0 )
{
pt = pu;
}
struct X;
struct Y;
int main()
{
// shared_ptr
assert_same_type< boost::pointer_to_other< boost::shared_ptr<X>, Y >::type, boost::shared_ptr<Y> >();
assert_same_type< boost::pointer_to_other< boost::shared_ptr<X>, void >::type, boost::shared_ptr<void> >();
assert_same_type< boost::pointer_to_other< boost::shared_ptr<void>, Y >::type, boost::shared_ptr<Y> >();
// shared_array
assert_same_type< boost::pointer_to_other< boost::shared_array<X>, Y >::type, boost::shared_array<Y> >();
assert_same_type< boost::pointer_to_other< boost::shared_array<X>, void >::type, boost::shared_array<void> >();
assert_same_type< boost::pointer_to_other< boost::shared_array<void>, Y >::type, boost::shared_array<Y> >();
// scoped_ptr
assert_same_type< boost::pointer_to_other< boost::scoped_ptr<X>, Y >::type, boost::scoped_ptr<Y> >();
assert_same_type< boost::pointer_to_other< boost::scoped_ptr<X>, void >::type, boost::scoped_ptr<void> >();
assert_same_type< boost::pointer_to_other< boost::scoped_ptr<void>, Y >::type, boost::scoped_ptr<Y> >();
// scoped_array
assert_same_type< boost::pointer_to_other< boost::scoped_array<X>, Y >::type, boost::scoped_array<Y> >();
assert_same_type< boost::pointer_to_other< boost::scoped_array<X>, void >::type, boost::scoped_array<void> >();
assert_same_type< boost::pointer_to_other< boost::scoped_array<void>, Y >::type, boost::scoped_array<Y> >();
// intrusive_ptr
assert_same_type< boost::pointer_to_other< boost::intrusive_ptr<X>, Y >::type, boost::intrusive_ptr<Y> >();
assert_same_type< boost::pointer_to_other< boost::intrusive_ptr<X>, void >::type, boost::intrusive_ptr<void> >();
assert_same_type< boost::pointer_to_other< boost::intrusive_ptr<void>, Y >::type, boost::intrusive_ptr<Y> >();
// auto_ptr
assert_same_type< boost::pointer_to_other< std::auto_ptr<X>, Y >::type, std::auto_ptr<Y> >();
assert_same_type< boost::pointer_to_other< std::auto_ptr<X>, void >::type, std::auto_ptr<void> >();
assert_same_type< boost::pointer_to_other< std::auto_ptr<void>, Y >::type, std::auto_ptr<Y> >();
// raw pointer
assert_same_type< boost::pointer_to_other< X *, Y >::type, Y * >();
assert_same_type< boost::pointer_to_other< X *, void >::type, void * >();
assert_same_type< boost::pointer_to_other< void *, Y >::type, Y * >();
return 0;
}

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
//
// scoped_array_eq_fail.cpp - a negative test for "p == q"
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/scoped_array.hpp>
int main()
{
boost::scoped_array<int> p, q;
p == q; // must fail
return 0;
}

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
//
// scoped_ptr_eq_fail.cpp - a negative test for "p == q"
//
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/scoped_ptr.hpp>
int main()
{
boost::scoped_ptr<int> p, q;
p == q; // 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, 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,42 @@ 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_TEST( p < r || r < p );
BOOST_TEST( r.get() == &v2 );
}
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

@@ -0,0 +1,146 @@
#include <boost/config.hpp>
// shared_ptr_alias_test.cpp
//
// Copyright (c) 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/detail/lightweight_test.hpp>
#include <boost/shared_ptr.hpp>
#include <memory>
#include <cstddef>
//
class incomplete;
struct X
{
int v_;
explicit X( int v ): v_( v )
{
}
~X()
{
v_ = 0;
}
};
int main()
{
{
int m = 0;
boost::shared_ptr< int > p;
boost::shared_ptr< int > p2( p, &m );
BOOST_TEST( p2.get() == &m );
BOOST_TEST( p2? true: false );
BOOST_TEST( !!p2 );
BOOST_TEST( p2.use_count() == p.use_count() );
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
p2.reset( p, 0 );
BOOST_TEST( p2.get() == 0 );
BOOST_TEST( p2? false: true );
BOOST_TEST( !p2 );
BOOST_TEST( p2.use_count() == p.use_count() );
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
}
{
int m = 0;
boost::shared_ptr< int > p( new int );
boost::shared_ptr< int const > p2( p, &m );
BOOST_TEST( p2.get() == &m );
BOOST_TEST( p2? true: false );
BOOST_TEST( !!p2 );
BOOST_TEST( p2.use_count() == p.use_count() );
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
boost::shared_ptr< int volatile > p3;
p2.reset( p3, 0 );
BOOST_TEST( p2.get() == 0 );
BOOST_TEST( p2? false: true );
BOOST_TEST( !p2 );
BOOST_TEST( p2.use_count() == p3.use_count() );
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
}
{
boost::shared_ptr< int > p( new int );
boost::shared_ptr< void const > p2( p, 0 );
BOOST_TEST( p2.get() == 0 );
BOOST_TEST( p2? false: true );
BOOST_TEST( !p2 );
BOOST_TEST( p2.use_count() == p.use_count() );
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
int m = 0;
boost::shared_ptr< void volatile > p3;
p2.reset( p3, &m );
BOOST_TEST( p2.get() == &m );
BOOST_TEST( p2? true: false );
BOOST_TEST( !!p2 );
BOOST_TEST( p2.use_count() == p3.use_count() );
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
}
{
boost::shared_ptr< incomplete > p;
boost::shared_ptr< incomplete > p2( p, 0 );
BOOST_TEST( p2.get() == 0 );
BOOST_TEST( p2? false: true );
BOOST_TEST( !p2 );
BOOST_TEST( p2.use_count() == p.use_count() );
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
p2.reset( p, 0 );
BOOST_TEST( p2.get() == 0 );
BOOST_TEST( p2? false: true );
BOOST_TEST( !p2 );
BOOST_TEST( p2.use_count() == p.use_count() );
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
}
{
boost::shared_ptr< X > p( new X( 5 ) );
boost::shared_ptr< int const > p2( p, &p->v_ );
BOOST_TEST( p2.get() == &p->v_ );
BOOST_TEST( p2? true: false );
BOOST_TEST( !!p2 );
BOOST_TEST( p2.use_count() == p.use_count() );
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
p.reset();
BOOST_TEST( *p2 == 5 );
boost::shared_ptr< X const > p3( new X( 8 ) );
p2.reset( p3, &p3->v_ );
BOOST_TEST( p2.get() == &p3->v_ );
BOOST_TEST( p2? true: false );
BOOST_TEST( !!p2 );
BOOST_TEST( p2.use_count() == p3.use_count() );
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
p3.reset();
BOOST_TEST( *p2 == 8 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,224 @@
#include <boost/config.hpp>
// shared_ptr_alloc2_test.cpp
//
// Copyright (c) 2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/detail/lightweight_test.hpp>
#include <boost/shared_ptr.hpp>
#include <memory>
#include <cstddef>
// test_allocator
struct test_allocator_base
{
int id_;
static int last_global_id_;
static int count_;
explicit test_allocator_base( int id ): id_( id )
{
}
};
int test_allocator_base::last_global_id_ = 0;
int test_allocator_base::count_ = 0;
template<class T> class test_allocator: public test_allocator_base
{
public:
typedef T * pointer;
typedef T const * const_pointer;
typedef T & reference;
typedef T const & const_reference;
typedef T value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
private:
static T * last_pointer_;
static std::size_t last_n_;
static int last_id_;
public:
template<class U> struct rebind
{
typedef test_allocator<U> other;
};
pointer address( reference r ) const
{
return &r;
}
const_pointer address( const_reference s ) const
{
return &s;
}
explicit test_allocator( int id = 0 ): test_allocator_base( id )
{
}
template<class U> test_allocator( test_allocator<U> const & r ): test_allocator_base( r )
{
}
template<class U> test_allocator & operator=( test_allocator<U> const & r )
{
test_allocator_base::operator=( r );
return *this;
}
void deallocate( pointer p, size_type n )
{
BOOST_TEST( p == last_pointer_ );
BOOST_TEST( n == last_n_ );
BOOST_TEST( id_ == last_id_ );
--count_;
::operator delete( p );
}
pointer allocate( size_type n, void const * )
{
T * p = static_cast< T* >( ::operator new( n * sizeof( T ) ) );
last_pointer_ = p;
last_n_ = n;
last_id_ = id_;
last_global_id_ = id_;
++count_;
return p;
}
void construct( pointer p, T const & t )
{
new( p ) T( t );
}
void destroy( pointer p )
{
p->~T();
}
size_type max_size() const
{
return size_type( -1 ) / sizeof( T );
}
};
template<class T> T * test_allocator<T>::last_pointer_ = 0;
template<class T> std::size_t test_allocator<T>::last_n_ = 0;
template<class T> int test_allocator<T>::last_id_ = 0;
template<class T, class U> inline bool operator==( test_allocator<T> const & a1, test_allocator<U> const & a2 )
{
return a1.id_ == a2.id_;
}
template<class T, class U> inline bool operator!=( test_allocator<T> const & a1, test_allocator<U> const & a2 )
{
return a1.id_ != a2.id_;
}
template<> class test_allocator<void>: public test_allocator_base
{
public:
typedef void * pointer;
typedef void const * const_pointer;
typedef void value_type;
template<class U> struct rebind
{
typedef test_allocator<U> other;
};
explicit test_allocator( int id = 0 ): test_allocator_base( id )
{
}
template<class U> test_allocator( test_allocator<U> const & r ): test_allocator_base( r )
{
}
template<class U> test_allocator & operator=( test_allocator<U> const & r )
{
test_allocator_base::operator=( r );
return *this;
}
};
//
struct X
{
static int instances;
X()
{
++instances;
}
~X()
{
--instances;
}
private:
X( X const & );
X & operator=( X const & );
};
int X::instances = 0;
int main()
{
BOOST_TEST( X::instances == 0 );
boost::shared_ptr<void> pv( new X, boost::checked_deleter<X>(), std::allocator<X>() );
BOOST_TEST( X::instances == 1 );
pv.reset( new X, boost::checked_deleter<X>(), test_allocator<float>( 42 ) );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( test_allocator_base::last_global_id_ == 42 );
BOOST_TEST( test_allocator_base::count_ > 0 );
pv.reset();
BOOST_TEST( X::instances == 0 );
BOOST_TEST( test_allocator_base::count_ == 0 );
pv.reset( new X, boost::checked_deleter<X>(), test_allocator<void>( 43 ) );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( test_allocator_base::last_global_id_ == 43 );
pv.reset( new X, boost::checked_deleter<X>(), std::allocator<void>() );
BOOST_TEST( X::instances == 1 );
pv.reset();
BOOST_TEST( X::instances == 0 );
return boost::report_errors();
}

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