Compare commits

...

362 Commits

Author SHA1 Message Date
Marshall Clow
9b964f6881 Release 1.55.0
[SVN r86621]
2013-11-11 19:45:21 +00:00
Peter Dimov
be06392771 Merged revision(s) 85995 from trunk: Remove #pragma intrinsic( _mm_pause ); not needed, not supported on Intel. Closes #6646, #7318.
[SVN r86417]
2013-10-24 14:05:26 +00:00
Andrey Semashev
fc20a29c99 Merged changes from trunk: added intrusive_ref_counter.
[SVN r85609]
2013-09-08 17:17:18 +00:00
Peter Dimov
6eefc6bf81 Merge [84506] from trunk: Document that constructors initialize enable_shared_from_this. Fixes #8573.
[SVN r84507]
2013-05-26 13:39:04 +00:00
Peter Dimov
9355404d10 Merged revision(s) 83914 from trunk:
Fix new double(n) to new double[n].

[SVN r83915]
2013-04-15 15:13:20 +00:00
Glen Fernandes
240c66e633 Merge revision(s) 83829 from trunk:
More small cosmetic documentation changes.
........

[SVN r83830]
2013-04-10 05:17:32 +00:00
Glen Fernandes
e497aec58a Merge revision(s) 83827 from trunk:
Small improvements to make_shared documentation.
........


[SVN r83828]
2013-04-10 05:03:45 +00:00
Peter Dimov
579b347267 Merged revision(s) 83198 from trunk: Avoid stack overflow in make_shared. Fixes #4256. Fixes #7965.
[SVN r83341]
2013-03-07 08:18:48 +00:00
Glen Fernandes
3178d38137 Merge revision 82971 from trunk:
Identifier renaming in allocate_array_helper, array_deleter, make_array_helper
function parameters to satisfy higher warning levels.
........


[SVN r82976]
2013-02-18 18:04:48 +00:00
Peter Dimov
e39fcad839 Merged revision(s) 82927 from trunk: Check for BOOST_NO_CXX11_RVALUE_REFERENCES in addition to BOOST_NO_CXX11_SMART_PTR. Fixes #8055.
[SVN r82928]
2013-02-16 17:21:23 +00:00
Glen Fernandes
de6dc3a26e Merge documentation fix from trunk
[SVN r82575]
2013-01-21 04:36:14 +00:00
Glen Fernandes
72095a4804 Merge revision 82408 from trunk:
Support BOOST_NO_EXCEPTIONS in detail/array_utility.hpp to allow use when exceptions are disabled
........


[SVN r82432]
2013-01-10 16:50:34 +00:00
Peter Dimov
dcc1713c59 Merged revision(s) 82351 from trunk: Replace std::nullptr_t with boost::detail::sp_nullptr_t.
[SVN r82427]
2013-01-09 23:41:31 +00:00
Peter Dimov
f6d5257597 Merged revision(s) 82349 from trunk: Update documentation for nullptr, owner_before, explicit operator bool.
[SVN r82357]
2013-01-04 18:44:47 +00:00
Peter Dimov
d3a549e93a Merged revision(s) 82188 from trunk: Untabify.
[SVN r82189]
2012-12-23 16:07:27 +00:00
Glen Fernandes
c55ffa1cab Merge Jamfile.v2 from trunk
[SVN r82084]
2012-12-18 19:09:57 +00:00
Peter Dimov
049d0698b7 Manually apply a change from [58306] that didn't get merged at the time.
[SVN r82026]
2012-12-16 16:20:03 +00:00
Peter Dimov
5ba3312519 Merged revision(s) 81900-81901 from trunk:
Replace use of BOOST_HAS_RVALUE_REFS with !BOOST_NO_CXX11_RVALUE_REFERENCES.
........
Replace use of BOOST_HAS_VARIADIC_TMPL with !BOOST_NO_CXX11_VARIADIC_TEMPLATES.
........


[SVN r81979]
2012-12-15 20:20:20 +00:00
Glen Fernandes
6a218a5ef2 Merged revision(s) 81886,81887,81894,81905 from trunk:
Use BOOST_NO_CXX11_RVALUE_REFERENCES and BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of the legacy macros. Rename identifiers of detail utility functions.
........
Two detail utility functions identifier renaming reverted
........
Remove -fno-deduce-init-list for certain tests in Jamfile.v2
........
Correct call to init_list in make_shared and allocate_shared. Move g++ failing case into separate test to not mask other issues.
........


[SVN r81945]
2012-12-14 18:35:03 +00:00
Peter Dimov
c14369aac9 Merged revision(s) 81860-81861 from trunk:
Change make_shared to use the new _internal_get_untyped_deleter. Fixes #6830.
........
Add allocate_shared_noinit.
........


[SVN r81899]
2012-12-13 14:57:12 +00:00
Peter Dimov
7ab4f6ce92 Merged revision(s) 72437 from trunk: Lock-free sp_counted_base for SNC/PS3, thanks Peter Dimov
[SVN r81898]
2012-12-13 14:53:09 +00:00
Glen Fernandes
c28bef2e9b Merged revision(s) 81858,81859,81865,81867 from trunk:
Add overloads of allocate_shared_noinit to complement make_shared_noinit
........
Explicitly name detail array construct overloads for different parameter types.
........
Use _internal_get_untyped_deleter in allocate_shared_array and make_shared_array
........
Documentation corrections: make_shared_array.html
........


[SVN r81882]
2012-12-12 22:57:03 +00:00
Glen Fernandes
5fc6fe474b Merged revision(s) 81844 from trunk:
Correct link to  http://www.stroustrup.com/wrapper.pdf in sp_techniques.html
........


[SVN r81863]
2012-12-11 18:42:48 +00:00
Peter Dimov
d42ce87557 Merged revision(s) 81780 from trunk: Use explicit operator bool when available; add nullptr support to shared_ptr. Fixes #4116.
[SVN r81862]
2012-12-11 18:35:21 +00:00
Glen Fernandes
b306c9751f Merged revision(s) 81748-81750,81752,81759,81782 from trunk:
Refactoring in detail array_deleter before adding support for special-casing trivially default-constructible construction and trivially destroyable destruction.
........
Special case array construction for trivially default-constructible types and array destruction for trivially-destroyable types.
........
Optimization in initialization overload of array_construct for compilers to optimize it into the equivalent of a memset
........
Correctly use r-value reference semantics for Args and T in array utilities
........
Change ordering of overload definitions in array_utility.hpp
........
Convert function parameter for inner array size into template parameter and make identifiers in array_deleter consistent with those in array_utility 
........


[SVN r81800]
2012-12-08 18:30:27 +00:00
Peter Dimov
c03bfd0b4d Merged revision(s) 81730-81731, 81776 from trunk:
Fix get_pointer for the array case, add operator= for unique_ptr, update auto_ptr signatures to use rvalue reference when available.
........
Update shared_ptr.htm.
........
Add more unique_ptr tests.
........


[SVN r81781]
2012-12-08 00:57:04 +00:00
Glen Fernandes
08e5894510 Merged revisions 81700,81703 from trunk:
Add overloads of make_shared and allocate_shared for arrays for E&& where E is typename boost::detail::array_base<T>::type
........
Update documentation and remove unused code.
........


[SVN r81716]
2012-12-05 04:28:20 +00:00
Glen Fernandes
3551d17566 Merged revision 81463 from trunk:
Update shared_ptr casts.
........


[SVN r81715]
2012-12-05 04:13:51 +00:00
Peter Dimov
32fe0b8f26 Merged revision(s) 81488 from trunk: Apply patch from #7722. Fixes #7722.
[SVN r81714]
2012-12-05 03:44:40 +00:00
Glen Fernandes
88c2baa20b Merged revision(s) 81684-81685 from trunk:
For fixed size arrays upon constructor exception thrown destroy correctly.
........
Minor cosmetic change in detail array_deleter
........


[SVN r81695]
2012-12-03 15:42:15 +00:00
Glen Fernandes
ea55019260 Merged revision(s) 81641-81643,81658,81669,81681 from trunk:
Use const T (&)[N] for fixed size arrays instead of std::initializer<T> in overloads of make_shared and allocate_shared for arrays.
........
Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead for certain overloads of make_shared and allocate_shared
........
Code consistency: Use the same style of #if conditional compilation checks in allocate_shared_array.hpp and make_shared_array.hpp.
........
Change make_shared and allocate_shared array form overload for size and inner array initialization list to use const T(&)[N] instead of std::initializer_list<T>.
........
Move two tests for allocate_shared and make_shared within check for BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
........
Make specializations of detail array_deleter consistent.
........


[SVN r81682]
2012-12-02 23:15:55 +00:00
Glen Fernandes
2346941b15 Merged revision(s) 81608-81610 from trunk:
Optimization: Add specializations of make_array_helper, allocate_array_helper, and array_deleter for fixed size arrays to avoid storing size.
........
Consistent formatting across overloads of make_shared and allocate_shared (array forms).
........
More consistency in type parameters in helper details of allocate_shared and make_shared.
........


[SVN r81635]
2012-11-30 17:29:36 +00:00
Peter Dimov
c7b6e56b30 Merged revision(s) 81368, 81399, 81407-81409, 81419, 81430-81431, 81437 from trunk:
Apply BOOST_NOEXCEPT patch. Refs #7523.
........
Replace std::forward with detail::sp_forward.
........
Cosmetic changes in make_shared_array.hpp and allocate_shared_array.hpp
........
Documentation of make_shared_array: Minor corrections
........
Make make_shared_array.hpp and allocate_shared_array.hpp consistent with namespace qualification in rest of smart_ptr.
........
Update smart_ptr.htm with link to make_shared_array.htm which lists the many overloads of make_shared and allocate_shared for arrays.
........
Update documentation for make_shared and allocate_shared array forms.
........
Minor corrections in make_shared_array.html documentation.
........
Borland fixes.
........


[SVN r81457]
2012-11-21 15:38:06 +00:00
Peter Dimov
215771c83d Merged [81348] from trunk. Fixes #7693.
[SVN r81367]
2012-11-16 14:11:25 +00:00
Peter Dimov
2805ae9362 Merged revision(s) 81341-81342 from trunk:
Add additional overload for allocate_shared and make_shared array forms that take initializer list of T for the array types T[M][N]
........
Minor style change: Fix indentation in allocate_shared_array.hpp and make_shared_array.hpp
........


[SVN r81366]
2012-11-16 14:09:18 +00:00
Peter Dimov
cb0797acf0 Merged revision(s) 81149, 81159, 81171, 81174, 81219-81220, 81222-81224, 81226, 81229-81239, 81242, 81253, 81257-81262, 81265-81268, 81271-81272, 81275-81277, 81299-81300 from trunk:
Implement shared_ptr<X[]>, weak_ptr<X[]>. Refs #1113.
........
Fix shared_ptr<T[]> EDG issues.
........
Disable make_shared<T> overloads when T is Q[].
........
Add catch(...) clauses to sp_array_test.cpp.
........
Add allocate_shared and make_shared for shared_ptr arrays of runtime size. Fulfills need for allocate_shared_array and make_shared_array. 
........
Update Jamfile.v2 to run make_shared array tests and allocate_shared array tests.
........
Fix g++ issues.
........
Add specialization of sp_if_not_array<T[N]>.
........
Rename make_shared.hpp to make_shared_object.hpp, include from make_shared.hpp.
........
Add make_shared_array_args_test.cpp.
........
Add support for make_shared of array of arrays. Correctly destroy elements and construct elements for the variadic template constructor variants.
........
Fix sp_convertible<T const[], T const[]>.
........
Update smart_ptr/detail/array_helper to have create and create_noinit for non-array case.
........
Rename sp_convertible_test.cpp to shared_ptr_convertible_test.cpp.
........
Don't treat array_helper create and create_noinit for array types as a special case.
........
Add sp_convertible_test.cpp.
........
Fix array_helper (create_noinit and use of args...).
........
Update allocate_shared and make_shared to treat multidimensional array as single dimension. Remove detail array_helper. Add detail array traits. Update tests. 
........
Simplify array_deleter interface
........
Add missing semicolon.
........
Fix typo.
........
Add tests for variadic template constructors overload of array forms of make_shared and allocate_shared for multidimensional arrays and up to 9 constructor arguments.
........
Add support for shared_ptr<X[N>.
........
Add C++11 initializer list support for make_shared and allocate_shared array forms.

........
Clean up code in allocate_shared_array.hpp and make_shared_array.hpp
........
Change make_shared and allocate_shared array form semantics with initializer lists overload that takes no size.
........
Disable make_shared for arrays when the compiler doesn't support partial specialization or SFINAE.
........
For allocate_shared and make_shared: Separate test case that g++ does support yet. Remove macros testing for no partial specialization in traits. Add additional traits.
........
Actually remove test cases from make_shared_array_create_test.cpp and allocate_shared_array_create_test.cpp that g++ does not handle.
........
Add overloads to support fixed size arrays, T[N], to allocate_shared (variadic) and make_shared (variadic) and make_shared_noinit.
........
Add additional overload for make_shared and allocate_shared for arrays for fixed size arrays and initializer lists.
........
Add assertion to overload of make_shared and allocate_shared for T[N] with initializer lists. Rename detail type to be more intuitive.
........
Add allocate_shared_array_args_test.cpp.
........
Keep old definition of sp_assert_convertible when BOOST_SP_NO_SP_CONVERTIBLE is set.
........
Updated shared_array to match shared_ptr. Refs #1113.
........
Add final overload of make_shared and allocate_shared (array forms) for T[][N] with C++11 initializer lists.
........
Change traits for initializer list for g++
........
Tidy long line formatting in allocate_shared_array.hpp and make_shared_array.hpp
........
Update tests for make_shared and allocate_shared array forms, for normal case, initializer lists, variadic template arguments, for arrays and fixed size arrays.
........
Update Jamfile.v2 with two new smart_ptr tests for allocate_shared and make_shared
........


[SVN r81339]
2012-11-14 13:52:11 +00:00
Peter Dimov
e8103f9774 Merge from 57197, 57206, 57423, 57518 did not apply to 'libs' for some reason; update.
[SVN r81338]
2012-11-14 13:36:44 +00:00
Peter Dimov
71eb435412 Merged revision(s) 57197, 57206, 57423, 57518 from trunk:
Renamed enable_shared_from_this2 to enable_shared_from_raw and
added shared_from_raw free function.  These changes fix the pointer 
value in shared_ptr which were obtained before an external shared_ptr has
taken ownership of the object (for example when a shared_ptr to
this is obtained in an object's constructor).


........
Brought back code which fixes get_deleter when it is called on a deleter 
which has been wrapped inside a deleter_wrapper by "shared_from_raw() in 
constructors" support.

........
Added weak_from_raw(), for use in conjunction with
enable_shared_from_raw base class.


........
Fixed access to enable_shared_from_raw::weak_this_ when 
BOOST_NO_MEMBER_TEMPLATE_FRIENDS is defined.


........


[SVN r81337]
2012-11-14 13:26:30 +00:00
Peter Dimov
4a2dad1574 Merged [81134] from trunk. Fixes #6308. Refs #6667.
[SVN r81336]
2012-11-14 12:09:30 +00:00
Peter Dimov
babc72757d Merged [81131] from trunk. Fixes #6625.
[SVN r81335]
2012-11-14 12:04:48 +00:00
Peter Dimov
c19cbc1892 Merged [81128] from trunk. Fixes #7141.
[SVN r81334]
2012-11-14 11:57:58 +00:00
Peter Dimov
d065e4d971 Merged [81127] from trunk. Fixes #6901.
[SVN r81333]
2012-11-14 11:55:10 +00:00
Peter Dimov
777b86a661 Merged [81126] from trunk. Fixes #6996.
[SVN r81332]
2012-11-14 11:53:05 +00:00
Peter Dimov
aae5440854 Merged [80988] from trunk.
[SVN r81331]
2012-11-14 11:51:00 +00:00
Peter Dimov
227d2e3255 Manually apply [69019] from trunk.
[SVN r81330]
2012-11-14 11:43:17 +00:00
Peter Dimov
8bf183b373 Merged [81125] from trunk. Fixes #4185.
[SVN r81329]
2012-11-14 11:20:29 +00:00
Peter Dimov
5017da2514 Merged [81119] from trunk. Fixes #7599.
[SVN r81328]
2012-11-14 11:17:48 +00:00
Peter Dimov
c2048732d8 Merge [77316] to release. Closes #6667.
[SVN r77318]
2012-03-12 17:40:02 +00:00
Peter Dimov
5979c1d4bd Merge [77315] to release. Closes #5331.
[SVN r77317]
2012-03-12 17:37:51 +00:00
Peter Dimov
3090f6f4af Merge [76219] to release. Fixes #6332.
[SVN r76221]
2011-12-29 22:43:02 +00:00
Peter Dimov
40073ef64f Merge [76125], [76126] to release.
[SVN r76164]
2011-12-26 00:25:42 +00:00
Peter Dimov
b9970eda45 Merge [76111] to release. Fixes #2603.
[SVN r76163]
2011-12-26 00:23:00 +00:00
Peter Dimov
9147489b4c Merge [76123] to release. Refs #6308.
[SVN r76124]
2011-12-23 23:12:50 +00:00
Peter Dimov
d1348ea05e Merge [76119] to release. Refs #6308.
[SVN r76120]
2011-12-23 15:10:51 +00:00
Peter Dimov
90db9a6435 Merge [76086] to release. Fixes #6308.
[SVN r76087]
2011-12-21 00:43:56 +00:00
Peter Dimov
1c208ad3ea Merge [75392] to release. Fixes #6087.
[SVN r75756]
2011-11-30 18:01:02 +00:00
Peter Dimov
5fc9bf5bc5 Merge [75390] to release. Fixes #4493.
[SVN r75754]
2011-11-30 17:51:43 +00:00
Peter Dimov
c846d230f0 Merge [75389] to release. Fixes #5372.
[SVN r75753]
2011-11-30 17:49:43 +00:00
Peter Dimov
7b097467d6 Merge [75385] to release. Fixes #6099.
[SVN r75386]
2011-11-07 15:05:43 +00:00
Peter Dimov
7cb040edb0 Merge [70452] to release. Fixes #5327.
[SVN r75381]
2011-11-07 14:25:23 +00:00
Peter Dimov
d6ac116b71 Merge [73202] to release.
[SVN r73542]
2011-08-05 08:58:31 +00:00
Peter Dimov
8abc8889d1 Merge [69262] to release. Fixes #5018.
[SVN r70447]
2011-03-23 00:13:54 +00:00
Peter Dimov
c5b47e2136 Merge [69261] to release. Fixes #5019.
[SVN r70441]
2011-03-22 23:55:05 +00:00
Peter Dimov
7c0815c567 Merge [69260] to release. Fixes #5216.
[SVN r70440]
2011-03-22 23:51:10 +00:00
Peter Dimov
210288f02e Merge [69251] to release. Fixes #4127.
[SVN r70439]
2011-03-22 23:45:59 +00:00
Peter Dimov
cf7b6904e8 Merge [69250] to release. Fixes #4256. Fixes #3875.
[SVN r70436]
2011-03-22 23:38:12 +00:00
Peter Dimov
b978919dd1 Merge [69246] to release. Fixes #4478.
[SVN r70435]
2011-03-22 23:29:35 +00:00
Peter Dimov
1086aff971 Merge [69245] to release. Fixes #4433.
[SVN r70434]
2011-03-22 23:23:44 +00:00
Peter Dimov
445e8d1728 Merge [69244] to release. Fixes #4892.
[SVN r70433]
2011-03-22 23:17:51 +00:00
Peter Dimov
545745d649 Merge [69242] to release. Fixes #4288. Fixes #5189.
[SVN r70432]
2011-03-22 23:05:48 +00:00
Hartmut Kaiser
d71cc6ab08 Merging from trunk
[SVN r66166]
2010-10-24 22:24:54 +00:00
Peter Dimov
0d77fd0678 Merge [62248] to release. Fixes #3856.
[SVN r63827]
2010-07-10 21:17:40 +00:00
Peter Dimov
6ca6d3ce6f Merge [62246] to release. Fixes #4217.
[SVN r63826]
2010-07-10 21:07:05 +00:00
Peter Dimov
cfc82854d3 Merge [62245] to release. Fixes #4199.
[SVN r63825]
2010-07-10 20:46:53 +00:00
Peter Dimov
b9d77d877e Merge [61344] to release. Fixes #4108.
[SVN r62244]
2010-05-26 17:34:01 +00:00
Peter Dimov
1f50e3abe4 Merge [61574], [61575], [61579] to release.
[SVN r62243]
2010-05-26 17:25:06 +00:00
Peter Dimov
697f338510 Merge [61074]. Fixes #4067.
[SVN r61078]
2010-04-05 19:37:32 +00:00
Peter Dimov
f4386409d9 Merge [58275], [58306] to release.
[SVN r58380]
2009-12-14 17:44:19 +00:00
Peter Dimov
ba349679f3 Merge [58123], [58127], [58128] to release. Fixes #3666.
[SVN r58195]
2009-12-06 17:50:28 +00:00
Peter Dimov
a3b84f8586 Merge [58094] to release.
[SVN r58122]
2009-12-03 17:50:37 +00:00
Peter Dimov
b0fd8a6b08 Merge [57957] to release. Fixes #3570.
[SVN r58067]
2009-11-30 20:34:39 +00:00
Peter Dimov
4f5062004a Merge [57954], [57955] to release.
[SVN r58066]
2009-11-30 20:30:22 +00:00
Peter Dimov
f040bed751 Merge [57953] to release. Fixes #2681.
[SVN r58065]
2009-11-30 20:25:01 +00:00
Peter Dimov
2f8945a885 Merge [57951] to release. Fixes #3351.
[SVN r58064]
2009-11-30 20:20:52 +00:00
Peter Dimov
2bd0778778 Merge [57949] to release. Fixes #3678. Fixes #3341.
[SVN r58063]
2009-11-30 20:17:14 +00:00
Peter Dimov
eec640bfd7 Merge [57520] to release. Fixes #2962.
[SVN r57960]
2009-11-26 22:10:30 +00:00
Peter Dimov
754fd941ee Merge [57950], [57952] to release. Fixes #3404. Fixes #3456.
[SVN r57959]
2009-11-26 21:58:16 +00:00
Troy D. Straszheim
e94f64039d rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Peter Dimov
63b17c24ea Merge [51909], [51912], [52937], [53672] to release.
[SVN r55479]
2009-08-08 23:21:15 +00:00
Troy D. Straszheim
8a421c2098 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Troy D. Straszheim
5fa1cbf6e1 shared_ptr and bind cmake tweaks
[SVN r53001]
2009-05-14 20:20:34 +00:00
Joaquín M López Muñoz
9f30442d1e merged [52456], [52457] and [52464] from trunk
[SVN r52486]
2009-04-19 10:17:50 +00:00
Peter Dimov
a4293f9dfa Merge [52454] to release. Fixes #2951.
[SVN r52472]
2009-04-18 21:32:43 +00:00
David Deakins
28de0cb1e3 Have config/select_stdlib_config.hpp and config/stdlib/stlport.hpp use <cstddef> instead of <utility> to determine which standard library is in use. For std lib implementations that rely on Boost components like TypeTraits, Bind, Function, or SmartPtr, this helps to avoid circular header dependency issues, since <cstddef> is much less likely to pull in Boost libraries than <utility>.
In get_pointer.hpp, switched to using <boost/config/no_tr1/memory.hpp> instead of using <memory> directly.  As above, this helps avoid circular header dependency issues in Boost-supplemented std libs (specifically it avoids issues when <memory> pulls in pieces of Boost.SmartPtr).

These two changes were made in response to testing done with STLport 5.2.1 using the _STLP_USE_BOOST_SUPPORT option.

[SVN r52221]
2009-04-06 21:25:18 +00:00
Peter Dimov
a1b4fc8d95 Merge [51978], [51985] to release. Closes #2885.
[SVN r52016]
2009-03-27 13:10:46 +00:00
Peter Dimov
77971c6ff5 Merge [51686] to release.
[SVN r51847]
2009-03-18 23:02:27 +00:00
Frank Mori Hess
1742c37942 Merged [51699] and [51700] from trunk to release.
Closes #1897


[SVN r51703]
2009-03-11 15:08:14 +00:00
Peter Dimov
31e06b4a1d Merge [51643] to release. Fixes #2813.
[SVN r51688]
2009-03-10 18:26:57 +00:00
Peter Dimov
22f1b092c9 Merge [51581] to release. Fixes #2126. Fixes #2584.
[SVN r51632]
2009-03-05 23:06:17 +00:00
Peter Dimov
5a2771e585 Merge [51518] to release. Closes #2814.
[SVN r51539]
2009-03-02 16:45:22 +00:00
Peter Dimov
dad59f3325 Merge [51517] to release. Closes #2525.
[SVN r51538]
2009-03-02 16:42:28 +00:00
Peter Dimov
bad394b1e9 Merge [51516] to release. Closes #2662.
[SVN r51537]
2009-03-02 16:39:53 +00:00
Peter Dimov
f93110620a Merge [51515] to release. Closes #2675.
[SVN r51536]
2009-03-02 16:37:31 +00:00
Peter Dimov
6be1e3fceb Merge [51514] to release. Closes #2394.
[SVN r51535]
2009-03-02 16:35:06 +00:00
Peter Dimov
cf91287732 Merge [51509], [51519] to release. Closes #2239.
[SVN r51531]
2009-03-02 16:22:16 +00:00
Peter Dimov
0da6902267 Move smart_ptr into boost/smart_ptr/*.hpp (refs #2239).
[SVN r51509]
2009-03-01 16:00:42 +00:00
Peter Dimov
10f6ff8b77 Sync smart_ptr/test/Jamfile.v2 with release.
[SVN r51486]
2009-02-28 21:08:25 +00:00
Peter Dimov
13f91c15f0 Sync enable_shared_from_this.hpp and shared_ptr.hpp with release.
[SVN r51485]
2009-02-28 20:02:12 +00:00
Peter Dimov
a2c5208b8e Sync shared_count.hpp with trunk.
[SVN r51484]
2009-02-28 19:59:56 +00:00
Troy D. Straszheim
55583ac749 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Michael A. Jackson
c40b306647 Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
Michael A. Jackson
d9b9921d23 Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
Nicola Musatti
6f91ea87c3 CodeGear patch. Fixes #2342
[SVN r49320]
2008-10-13 19:22:17 +00:00
Nicola Musatti
ed79000ea8 Patch from Ticket #2342
[SVN r49153]
2008-10-06 20:17:18 +00:00
Peter Dimov
6e804e64b8 Merge 48832-48840 from trunk.
[SVN r48989]
2008-09-28 15:05:17 +00:00
Peter Dimov
395766e2d3 Fix #2315.
[SVN r48839]
2008-09-17 22:59:07 +00:00
Peter Dimov
774332f85a Fix #2263. See also [48835].
[SVN r48838]
2008-09-17 22:53:53 +00:00
Peter Dimov
f5990cab65 Fix #1758. V9 is the default for g++ 4.2 or later, on 4.1 and earlier do not attempt to use CAS on V8.
[SVN r48837]
2008-09-17 22:49:18 +00:00
Peter Dimov
6175baf858 Fix #2000.
[SVN r48836]
2008-09-17 22:43:14 +00:00
Peter Dimov
2fb567b3f2 Fix #2336.
[SVN r48835]
2008-09-17 22:37:13 +00:00
Peter Dimov
2b25579338 Fix #2310.
[SVN r48834]
2008-09-17 22:31:13 +00:00
Peter Dimov
a97cd2d0cc Fix #2337.
[SVN r48833]
2008-09-17 22:21:56 +00:00
Peter Dimov
e3b9389a24 Fix #2338.
[SVN r48832]
2008-09-17 22:17:29 +00:00
Peter Dimov
6ba78f76f6 Merge 47736 from trunk (untabify).
[SVN r47739]
2008-07-23 20:47:47 +00:00
Peter Dimov
8c7954a53a Untabify.
[SVN r47736]
2008-07-23 20:04:52 +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
77ab953171 Updated atomic access syntax to match N2674 and the WD.
[SVN r47357]
2008-07-12 16:07:20 +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
2a92df56f2 #include <ia64intrin.h> in spinlock_sync.hpp as well.
[SVN r46055]
2008-06-02 20:01:30 +00:00
Peter Dimov
a9cd84f43d Fix #1938 in release
[SVN r45691]
2008-05-23 20:30:15 +00:00
Peter Dimov
366472fc35 Fix #1938 in trunk
[SVN r45690]
2008-05-23 20:29:14 +00:00
Peter Dimov
2bfe13c9c4 Renamed CRITICAL_SECTION to critical_section to avoid ambiguity.
[SVN r45545]
2008-05-19 15:09:54 +00:00
John Maddock
83e2510ce5 Use the "no_tr1" version of <functional>: addition of Boost.Exception support to throw_exception has created new cyclic dependencies with Boost.TR1.
[SVN r45422]
2008-05-16 11:12:32 +00:00
Peter Dimov
31685fe551 Updated Borland workaround to properly use BOOST_NO_MEMBER_TEMPLATE_FRIENDS.
[SVN r45347]
2008-05-14 00:21:28 +00:00
Peter Dimov
05e050abe0 Disable sp_convertible for Borland 5.x.
[SVN r45346]
2008-05-13 23:53:12 +00:00
Ion Gaztañaga
d261079616 Replaced non-ascii characters, ticket 1736
[SVN r45225]
2008-05-08 19:22:16 +00:00
Ion Gaztañaga
d52878df88 Replaced non-ascii characters, ticket 1736
[SVN r45224]
2008-05-08 19:08:38 +00:00
Peter Dimov
4b0490c0ae Fix sp_convertible_test.cpp failure in C++0x mode.
[SVN r45194]
2008-05-07 10:15:16 +00:00
Peter Dimov
2f1b1acc7a Fix g++ 3.2 regression.
[SVN r45177]
2008-05-06 18:58:15 +00:00
Peter Dimov
f0f9f72be6 sp_atomic_mt2_test.cpp added.
[SVN r45094]
2008-05-03 22:47:35 +00:00
Peter Dimov
efdc390bc9 intrusive_ptr::reset() added.
[SVN r45089]
2008-05-03 20:12:25 +00:00
Peter Dimov
d13f1d8694 More fixes for MSVC 6.0.
[SVN r45086]
2008-05-03 19:43:52 +00:00
Peter Dimov
83c43617af Fixes for MSVC 6.0.
[SVN r45085]
2008-05-03 19:29:01 +00:00
Peter Dimov
da323af72d Fixes for old compilers.
[SVN r45069]
2008-05-03 15:33:06 +00:00
Peter Dimov
0c4aaef77c Fix #1106.
[SVN r45068]
2008-05-03 15:07:58 +00:00
Ralf W. Grosse-Kunstleve
440fcb7ba0 missing workaround.hpp include added
[SVN r45040]
2008-05-02 19:44:56 +00:00
Peter Dimov
18a6c1add8 make_shared added; tweaks for old compilers; fixes #1884.
[SVN r44979]
2008-05-01 16:50:39 +00:00
Daniel Frey
357d3c4d54 Fixed comment to reflect the intention and the current code
[SVN r44873]
2008-04-29 05:32:13 +00:00
Anthony Williams
4bb747fb27 reverted accidental change
[SVN r44839]
2008-04-28 09:04:40 +00:00
Anthony Williams
f13591ef2b Added detail::try_lock_wrapper for use as scoped_try_lock typedefs, to fix issue #1873
[SVN r44838]
2008-04-28 09:00:58 +00:00
Daniel Frey
e3422efec6 Improved sp_deleter_wrapper implementation
[SVN r44837]
2008-04-28 07:17:11 +00:00
Daniel Frey
a01e4c3f83 Refactored and optimized enable_shared_from_this
[SVN r44782]
2008-04-26 19:59:11 +00:00
Daniel Frey
6f8dc5923c Added new reset()-counterparts for the new ctors
[SVN r44777]
2008-04-26 15:42:13 +00:00
Peter Dimov
7dc6b3d810 Added a few more tests.
[SVN r44775]
2008-04-26 13:39:52 +00:00
Daniel Frey
2251b1d2df No need for the new ctors to be templates
[SVN r44772]
2008-04-26 06:36:59 +00:00
Daniel Frey
8b3907ae81 Remove dynamic_cast in init_internal_shared_once()
[SVN r44744]
2008-04-23 19:32:44 +00:00
Daniel Frey
77f2d3f614 Reduce enable_shared_from_this overhead (replace _internal_shared_ptr by _internal_shared_count)
[SVN r44730]
2008-04-23 06:12:39 +00:00
Peter Dimov
93545d5cf2 Silence an g++ -Wextra warning.
[SVN r44728]
2008-04-23 00:33:58 +00:00
Daniel Frey
9e92c6354c Reduce enable_shared_from_this overhead
[SVN r44724]
2008-04-22 19:48:39 +00:00
Daniel Frey
e12ed6864b Avoid unneccessary increment/decrement of reference count
[SVN r44711]
2008-04-22 06:31:32 +00:00
Peter Dimov
b541145a60 Honor BOOST_NO_TEMPLATED_IOSTREAMS.
[SVN r44707]
2008-04-21 23:01:51 +00:00
Jürgen Hunold
ca344809ba Remove trailing comma at end of enumerator list (gcc 4.x -pedantic error)
[SVN r44686]
2008-04-21 08:07:55 +00:00
Peter Dimov
7802c695ef sp_atomic_mt_test.cpp added.
[SVN r44640]
2008-04-20 17:00:58 +00:00
Peter Dimov
71fa2cd658 Factored out boost/detail/lightweight_thread.hpp.
[SVN r44638]
2008-04-20 15:37:08 +00:00
Peter Dimov
04be979670 Atomic access added.
[SVN r44636]
2008-04-20 14:59:12 +00:00
John Maddock
35f2af947c Changed #includes to avoid circular dependencies between shared_ptr and TR1.
[SVN r44595]
2008-04-19 16:28:00 +00:00
Frank Mori Hess
3a578ac7c1 Added another BOOST_ASSERT to enable_shared_from_this::_internal_accept_owner.
[SVN r44499]
2008-04-17 13:40:44 +00:00
Frank Mori Hess
9365853fde Avoid needless overhead of wrapping owner's deleter in deleter_wrapper if
shared_from_this has not been called yet, as Peter suggested
earlier.



[SVN r44448]
2008-04-16 00:06:29 +00:00
Peter Dimov
16828c9c0a Disabled sync use for hppa.
[SVN r44441]
2008-04-15 19:02:13 +00:00
Peter Dimov
2fe899cdfe Disable sync use for arm and hppa.
[SVN r44440]
2008-04-15 18:57:46 +00:00
Peter Dimov
b45d011d5a Honor BOOST_DISABLE_THREADS; route GCC/ARM to the spinlock implementation; fall back to the spinlock implementation instead of using pthread_mutex.
[SVN r44369]
2008-04-13 15:35:40 +00:00
Peter Dimov
4094c23537 sp_accept_owner added.
[SVN r44353]
2008-04-12 18:22:18 +00:00
Peter Dimov
f85a1bf406 shared_ptr::lock no longer requires exceptions.
[SVN r44344]
2008-04-12 14:27:22 +00:00
Peter Dimov
dbd62686a3 ARM assembly fix.
[SVN r44140]
2008-04-09 23:19:22 +00:00
Peter Dimov
e4f638025c spinlock_gcc_arm.hpp added.
[SVN r44138]
2008-04-09 21:08:39 +00:00
Peter Dimov
d8296b3933 sp_counted_base_spin.hpp added, enabled by BOOST_SP_USE_SPINLOCK.
[SVN r44137]
2008-04-09 19:58:54 +00:00
Peter Dimov
b4885a1dd6 Proper try_lock semantics.
[SVN r44132]
2008-04-09 17:49:20 +00:00
Peter Dimov
748b1baee8 detail/spinlock_pool.hpp added.
[SVN r44074]
2008-04-06 16:53:11 +00:00
Peter Dimov
4880292c07 Add MT runs of yield_k_test and spinlock_try_test.
[SVN r44073]
2008-04-06 16:23:42 +00:00
Peter Dimov
6b25c57712 BOOST_COMPILER_FENCE factored out.
[SVN r44058]
2008-04-05 16:32:49 +00:00
Peter Dimov
373c52efa3 BOOST_SMT_PAUSE factored out.
[SVN r44056]
2008-04-05 15:23:28 +00:00
Peter Dimov
acb6824ef7 spinlock_nt.hpp added, Cygwin fixes.
[SVN r44055]
2008-04-05 15:06:31 +00:00
Peter Dimov
316d00c3fc Fix #1759 in release.
[SVN r44005]
2008-04-02 21:52:08 +00:00
Peter Dimov
515be965bd Fix #1759 in trunk.
[SVN r44004]
2008-04-02 21:42:52 +00:00
Peter Dimov
6ef32e1627 boost::detail::spinlock added.
[SVN r43950]
2008-03-30 16:33:58 +00:00
Peter Dimov
2452705117 Missing "inline" added.
[SVN r43916]
2008-03-28 20:44:45 +00:00
Peter Dimov
bb076d67e6 detail::yield(k) added.
[SVN r43888]
2008-03-27 22:20:11 +00:00
Peter Dimov
b08789b784 Silence unused parameter warning.
[SVN r43887]
2008-03-27 22:13:55 +00:00
Peter Dimov
5df69a8946 Added "Throws: nothing" to get_deleter.
[SVN r43873]
2008-03-26 18:34:29 +00:00
Peter Dimov
dc6a8f0696 _internal_accept_owner now checks if _owned isn't already true.
[SVN r43856]
2008-03-25 15:46:40 +00:00
Peter Dimov
af7d4fabad New enable_shared_from_this tests, fix.
[SVN r43829]
2008-03-24 16:00:28 +00:00
Frank Mori Hess
d17a096407 Fixed compile error with new enable_shared_from_this code,
reported by Tim Blechmann 


[SVN r43823]
2008-03-24 15:07:00 +00:00
Frank Mori Hess
d7448b5746 Added a little more test code for new enable_shared_from_this behavior.
[SVN r43804]
2008-03-23 14:51:40 +00:00
Frank Mori Hess
f22516d650 Fixed bogus test failure caused by new enable_shared_from_this features.
[SVN r43782]
2008-03-21 21:12:21 +00:00
Frank Mori Hess
b30aa1468a Worked around compilation error in boost::get_deleter when using old versions
of g++.



[SVN r43766]
2008-03-21 19:19:25 +00:00
Peter Dimov
5b17f88f0e Initialize _owned in the copy constructor as well.
[SVN r43739]
2008-03-20 22:10:52 +00:00
Frank Mori Hess
1c2d780f9e Added support for calling enable_shared_from_this::shared_from_this in
constructors.  Closes #1696.



[SVN r43738]
2008-03-20 19:32:43 +00:00
Peter Dimov
2eb3991630 Regression test for enable_shared_from_this.
[SVN r43733]
2008-03-19 19:39:50 +00:00
Peter Dimov
3a4dc43924 Fix #398, as long as the macros BOOST_NO_STD_TYPEINFO and BOOST_NO_IOSTREAM are defined. I don't know how Boost.Config needs to be changed to autodetect eVC4 and set these on its own.
[SVN r43318]
2008-02-19 14:26:36 +00:00
Peter Dimov
a055d9829e Fixes #1444.
[SVN r43317]
2008-02-19 14:01:13 +00:00
Peter Dimov
f596092bac Fixes #1590.
[SVN r43316]
2008-02-19 13:18:58 +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
Daniel James
7ca6d86bdc Point links to the pages that used to be in 'more' to the site.
[SVN r43210]
2008-02-10 15:02:17 +00:00
Daniel James
b2a3c9e59d Link to people pages on the website, as they've been removed from the download.
[SVN r43209]
2008-02-10 14:56:22 +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
Peter Dimov
e6f6ec9fa3 Attempt unspecified bool fix for Sun 5.7-5.9
[SVN r40914]
2007-11-07 22:47:55 +00:00
Peter Dimov
f854829d86 Port unspecified_bool fix for Sun 5.8 from RC_1_34
[SVN r40708]
2007-11-02 23:46:04 +00:00
Boris Gubenko
7b5beeedde fix typo in comment
[SVN r40605]
2007-10-30 12:58:36 +00:00
Boris Gubenko
9e41d1f194 add support for aC++ on HP-UX ia64
[SVN r40604]
2007-10-30 12:48:44 +00:00
Boris Gubenko
f49a2fb1e1 add support for aC++ on HP-UX ia64
[SVN r40603]
2007-10-30 12:43:47 +00:00
Beman Dawes
87c6b6b403 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
Peter Dimov
9db307eda5 defined(__ppc) added (Daniel P Furlani)
[SVN r39427]
2007-09-20 20:46:56 +00:00
Peter Dimov
5a85c1f0f2 CINT support (Nils Krumnack)
[SVN r39282]
2007-09-14 19:19:09 +00:00
Peter Dimov
f5ce4dbc4c Fixes #1243
[SVN r39199]
2007-09-11 20:58:19 +00:00
Peter Dimov
b2354d0a5e BOOST_NO_TYPEID support (#1108).
[SVN r38977]
2007-08-26 20:35:52 +00:00
Peter Dimov
e0ca42bb88 BOOST_NO_TYPEID support (#1108).
[SVN r38976]
2007-08-26 20:34:40 +00:00
Peter Dimov
bca336bf35 Updated the unspecified_bool_type to match shared_ptr.
[SVN r38975]
2007-08-26 19:42:50 +00:00
Vladimir Prus
6646d8acd2 Remove V1 Jamfiles
[SVN r38516]
2007-08-08 19:02:26 +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
Peter Dimov
ecb41cb150 sp_unary_addr_test added (reported by Scott French)
[SVN r38137]
2007-07-04 16:35:44 +00:00
Peter Dimov
ed8db8b5f2 Switched to BSL, Darin Adler has given blanket permission
[SVN r37917]
2007-06-06 16:39:52 +00:00
Peter Dimov
4ba37fce95 Negative test for conversion to void*
[SVN r37756]
2007-05-23 23:22:45 +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
5b57eff9b8 atomic_count_gcc_x86 added since _sync doesn't work on i386
[SVN r37637]
2007-05-08 20:14:38 +00:00
Peter Dimov
f980da560a Use __sync intrinsics on g++ 4.1+
[SVN r37528]
2007-04-28 18:13:12 +00:00
Peter Dimov
ffba68221b Use __sync intrinsics on g++ 4.1+
[SVN r37527]
2007-04-28 16:15:13 +00:00
Peter Dimov
4d45e5b9b5 Move tests added
[SVN r37526]
2007-04-28 15:49:13 +00:00
Peter Dimov
86d3f0aba7 Changed move constructors/assignments to leave the source empty
[SVN r37439]
2007-04-15 02:47:45 +00:00
Peter Dimov
66a25bd4a9 Move support
[SVN r37434]
2007-04-13 22:04:22 +00:00
Peter Dimov
745dbedbaa Fix CW regression re strcmp, strcpy
[SVN r37407]
2007-04-09 22:24:37 +00:00
Peter Dimov
26f83e75ef intrusive_ptr::reset added
[SVN r37406]
2007-04-09 21:35:07 +00:00
Peter Dimov
ce72827dc7 Aliasing support
[SVN r37405]
2007-04-09 18:48:47 +00:00
Peter Dimov
6e8f075d42 make_shared removed
[SVN r37404]
2007-04-09 18:42:49 +00:00
Peter Dimov
ae6c180be8 _MANAGED fix for sp_enable_shared_from_this
[SVN r37403]
2007-04-09 16:37:30 +00:00
Peter Dimov
54e12d03fd Aliasing constructor added
[SVN r37402]
2007-04-09 16:32:45 +00:00
Peter Dimov
469578e976 Fix C++0x ambiguity between boost::shared_ptr and std::shared_ptr
[SVN r37374]
2007-04-06 00:23:17 +00:00
Peter Dimov
97118668e2 Fix compare_fail failure
[SVN r37373]
2007-04-06 00:21:41 +00:00
Peter Dimov
1c3813ce52 BOOST_ASSERTs added (SF patch 1612733 by 'Baraclese')
[SVN r36316]
2006-12-10 21:01:55 +00:00
Peter Dimov
b440e85452 Fixed get_deleter comment
[SVN r36229]
2006-12-01 14:24:58 +00:00
Peter Dimov
d889751bc0 License/copyright edits
[SVN r35957]
2006-11-09 20:24:23 +00:00
Peter Dimov
0609322489 License/copyright edits
[SVN r35957]
2006-11-09 20:24:23 +00:00
Peter Dimov
b215e34650 License/copyright edits
[SVN r35956]
2006-11-09 20:17:14 +00:00
Peter Dimov
2f70e81b73 TR1 conformance fix
[SVN r35949]
2006-11-09 12:21:28 +00:00
Peter Dimov
6284a1abef TR1 conformance fix
[SVN r35948]
2006-11-09 12:15:23 +00:00
Beman Dawes
c464a07ab1 Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
Beman Dawes
41d4167533 Add copyright, license
[SVN r35905]
2006-11-07 19:11:57 +00:00
Peter Dimov
4a98c2931c Patch #1551992 (Michael Fink)
[SVN r35882]
2006-11-06 17:25:59 +00:00
Peter Dimov
75bc821afd 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
39551bdc1a A negative test for p > q added.
[SVN r34509]
2006-07-11 23:17:17 +00:00
Peter Dimov
6412de1dd5 TR1 cyclic dependency fixes.
[SVN r34499]
2006-07-10 13:17:41 +00:00
Peter Dimov
8d2f7fc5ef g++/SPARC version by Piotr Wyderski, thanks to Tomas Puverle and Michael van der Westhuizen
[SVN r34480]
2006-07-08 17:44:55 +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
ffd73c39b3 Solaris implementation by Michael van der Westhuizen
[SVN r34450]
2006-07-03 10:02:46 +00:00
Peter Dimov
4fcee64483 New, improved and more portable unspecified bool type. I hope.
[SVN r33987]
2006-05-17 22:39:34 +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
203764eb51 Fix VC6 codegen issue (Alain Cormier)
[SVN r33747]
2006-04-19 21:03:18 +00:00
Peter Dimov
6e120f4bf1 Fix VC6 codegen issue (Alain Cormier)
[SVN r33747]
2006-04-19 21:03:18 +00:00
Peter Dimov
747c9a1d3e Rvalue auto_ptr constructor is no longer explicit.
[SVN r33526]
2006-03-29 19:19:14 +00:00
Peter Dimov
7ce5b55f5c Fix issues on HP-UX (ILP32 model)
[SVN r33464]
2006-03-24 00:38:22 +00:00
Peter Dimov
e38d0daaab Fix issues on HP-UX (ILP32 model)
[SVN r33449]
2006-03-22 22:46:53 +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
263 changed files with 22279 additions and 3954 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>
@@ -30,20 +29,24 @@
and <STRONG>shared_ptr&lt;T const&gt;</STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
<h3><a name="Example">Example</a></h3>
<pre>
class Y: public enable_shared_from_this&lt;Y&gt;
#include &lt;boost/enable_shared_from_this.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
#include &lt;cassert&gt;
class Y: public boost::enable_shared_from_this&lt;Y&gt;
{
public:
shared_ptr&lt;Y&gt; f()
boost::shared_ptr&lt;Y&gt; f()
{
return shared_from_this();
}
}
};
int main()
{
shared_ptr&lt;Y&gt; p(new Y);
shared_ptr&lt;Y&gt; q = p-&gt;f();
boost::shared_ptr&lt;Y&gt; p(new Y);
boost::shared_ptr&lt;Y&gt; q = p-&gt;f();
assert(p == q);
assert(!(p &lt; q || q &lt; p)); // p and q must share ownership
}
@@ -85,9 +88,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,7 +1,9 @@
// Boost scoped_ptr_example implementation file -----------------------------//
// Copyright Beman Dawes 2001.
// See accompanying license for terms and conditions of use.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/smart_ptr for documentation.

View File

@@ -1,7 +1,9 @@
// Boost scoped_ptr_example header file ------------------------------------//
// Copyright Beman Dawes 2001.
// See accompanying license for terms and conditions of use.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/smart_ptr for documentation.

View File

@@ -1,7 +1,9 @@
// Boost scoped_ptr_example_test main program -------------------------------//
// Copyright Beman Dawes 2001.
// See accompanying license for terms and conditions of use.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/smart_ptr for documentation.

View File

@@ -1,7 +1,9 @@
// Boost shared_ptr_example.cpp --------------------------------------------//
// Copyright Beman Dawes 2001.
// See accompanying license for terms and conditions of use.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/smart_ptr for documentation.

View File

@@ -1,7 +1,9 @@
// Boost shared_ptr_example2 implementation file -----------------------------//
// Copyright Beman Dawes 2001.
// See accompanying license for terms and conditions of use.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/smart_ptr for documentation.

View File

@@ -1,7 +1,9 @@
// Boost shared_ptr_example2 header file -----------------------------------//
// Copyright Beman Dawes 2001.
// See accompanying license for terms and conditions of use.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/smart_ptr for documentation.

View File

@@ -1,7 +1,9 @@
// Boost shared_ptr_example2_test main program ------------------------------//
// Copyright Beman Dawes 2001.
// See accompanying license for terms and conditions of use.
// Copyright Beman Dawes 2001. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/smart_ptr for documentation.

View File

@@ -12,103 +12,10 @@
//
// 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.
//
// typedef <implementation-defined> boost::detail::atomic_count;
//
// atomic_count a(n);
//
// (n is convertible to long)
//
// Effects: Constructs an atomic_count with an initial value of n
//
// a;
//
// Returns: (long) the current value of a
//
// ++a;
//
// Effects: Atomically increments the value of a
// Returns: nothing
//
// --a;
//
// Effects: Atomically decrements the value of a
// Returns: (long) zero if the new value of a is zero,
// unspecified non-zero value otherwise (usually the new value)
//
// Important note: when --a returns zero, it must act as a
// read memory barrier (RMB); i.e. the calling thread must
// have a synchronized view of the memory
//
// On Intel IA-32 (x86) memory is always synchronized, so this
// is not a problem.
//
// On many architectures the atomic instructions already act as
// a memory barrier.
//
// This property is necessary for proper reference counting, since
// a thread can update the contents of a shared object, then
// release its reference, and another thread may immediately
// release the last reference causing object destruction.
//
// The destructor needs to have a synchronized view of the
// object to perform proper cleanup.
//
// Original example by Alexander Terekhov:
//
// Given:
//
// - a mutable shared object OBJ;
// - two threads THREAD1 and THREAD2 each holding
// a private smart_ptr object pointing to that OBJ.
//
// t1: THREAD1 updates OBJ (thread-safe via some synchronization)
// and a few cycles later (after "unlock") destroys smart_ptr;
//
// t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization
// with respect to shared mutable object OBJ; OBJ destructors
// are called driven by smart_ptr interface...
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
// Note: atomic_count_linux.hpp has been disabled by default; see the
// comments inside for more info.
#include <boost/config.hpp>
#ifndef BOOST_HAS_THREADS
namespace boost
{
namespace detail
{
typedef long atomic_count;
}
}
#elif defined(BOOST_USE_ASM_ATOMIC_H)
# include <boost/detail/atomic_count_linux.hpp>
#elif defined(BOOST_AC_USE_PTHREADS)
# include <boost/detail/atomic_count_pthreads.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# include <boost/detail/atomic_count_win32.hpp>
#elif defined(__GLIBCPP__)
# include <boost/detail/atomic_count_gcc.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_AC_USE_PTHREADS
# include <boost/detail/atomic_count_pthreads.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error
#error Unrecognized threading platform
#endif
#include <boost/smart_ptr/detail/atomic_count.hpp>
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED

View File

@@ -1,61 +0,0 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
//
// boost/detail/atomic_count_gcc.hpp
//
// atomic_count for GNU libstdc++ v3
//
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2002 Lars Gullik Bj<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>
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count(long v) : value_(v) {}
void operator++()
{
__atomic_add(&value_, 1);
}
long operator--()
{
return !__exchange_and_add(&value_, -1);
}
operator long() const
{
return __exchange_and_add(&value_, 0);
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
_Atomic_word value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_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

@@ -1,98 +0,0 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/atomic_count_win32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov
//
// 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
namespace boost
{
namespace detail
{
#ifndef BOOST_USE_WINDOWS_H
#ifdef _WIN64
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
extern "C" long_type __cdecl _InterlockedIncrement(long volatile *);
extern "C" long_type __cdecl _InterlockedDecrement(long volatile *);
#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)
inline long InterlockedIncrement(long volatile * lp)
{
return _InterlockedIncrement(lp);
}
inline long InterlockedDecrement(long volatile* lp)
{
return _InterlockedDecrement(lp);
}
#else // _WIN64
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile *);
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile *);
#endif // _WIN64
#endif // #ifndef BOOST_USE_WINDOWS_H
class atomic_count
{
public:
explicit atomic_count(long v): value_(v)
{
}
long operator++()
{
// Some older <windows.h> versions do not accept volatile
return InterlockedIncrement(const_cast<long*>(&value_));
}
long operator--()
{
return InterlockedDecrement(const_cast<long*>(&value_));
}
operator long() const
{
return value_;
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
volatile long value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED

View File

@@ -12,88 +12,11 @@
//
// 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
//
// * Used by the smart pointer library
// * Performance oriented
// * Header-only implementation
// * Small memory footprint
// * Not a general purpose mutex, use boost::mutex, CRITICAL_SECTION or
// pthread_mutex instead.
// * Never spin in a tight lock/do-something/unlock loop, since
// lightweight_mutex does not guarantee fairness.
// * Never keep a lightweight_mutex locked for long periods.
//
// The current implementation can use a pthread_mutex, a CRITICAL_SECTION,
// or a platform-specific spinlock.
//
// You can force a particular implementation by defining BOOST_LWM_USE_PTHREADS,
// BOOST_LWM_USE_CRITICAL_SECTION, or BOOST_LWM_USE_SPINLOCK.
//
// If neither macro has been defined, the default is to use a spinlock on Win32,
// and a pthread_mutex otherwise.
//
// Note that a spinlock is not a general synchronization primitive. In particular,
// it is not guaranteed to be a memory barrier, and it is possible to "livelock"
// if a lower-priority thread has acquired the spinlock but a higher-priority
// thread is spinning trying to acquire the same lock.
//
// For these reasons, spinlocks have been disabled by default except on Windows,
// where a spinlock can be several orders of magnitude faster than a CRITICAL_SECTION.
// Note: lwm_linux.hpp has been disabled by default; see the comments
// inside for more info.
#include <boost/config.hpp>
// Note to implementors: if you write a platform-specific spinlock
// for a platform that supports pthreads, be sure to test its performance
// against the pthreads-based version using shared_ptr_timing_test.cpp and
// shared_ptr_mt_test.cpp. Custom versions are usually not worth the trouble
// _unless_ the performance gains are substantial.
//
// Be sure to compare against a "real" pthreads library;
// shared_ptr_timing_test.cpp will compile succesfully with a stub do-nothing
// pthreads library, since it doesn't create any threads.
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(BOOST_LWM_USE_CRITICAL_SECTION) && !defined(BOOST_LWM_USE_PTHREADS)
# define BOOST_LWM_WIN32
#endif
#if !defined(BOOST_HAS_THREADS)
# if defined(BOOST_LWM_WIN32)
# include <boost/detail/lwm_win32_nt.hpp>
# else
# include <boost/detail/lwm_nop.hpp>
# endif
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(BOOST_USE_ASM_ATOMIC_H)
# include <boost/detail/lwm_linux.hpp>
#elif defined(BOOST_LWM_USE_CRITICAL_SECTION)
# include <boost/detail/lwm_win32_cs.hpp>
#elif defined(BOOST_LWM_USE_PTHREADS)
# include <boost/detail/lwm_pthreads.hpp>
#elif defined(BOOST_LWM_WIN32)
# include <boost/detail/lwm_win32.hpp>
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__sgi)
# include <boost/detail/lwm_irix.hpp>
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__GLIBCPP__)
# include <boost/detail/lwm_gcc.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_LWM_USE_PTHREADS
# include <boost/detail/lwm_pthreads.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error
# error Unrecognized threading platform
#endif
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED

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,74 +0,0 @@
#ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
#define BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
//
// boost/detail/lwm_irix.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2002 Dan Gohman
//
// 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,85 +0,0 @@
#ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
#define BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
//
// boost/detail/lwm_linux.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// 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,38 +0,0 @@
#ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
#define BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lwm_nop.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// 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.
//
namespace boost
{
namespace detail
{
class lightweight_mutex
{
public:
typedef lightweight_mutex scoped_lock;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED

View File

@@ -1,123 +0,0 @@
#ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
#define BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lwm_win32.hpp
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// 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,64 +0,0 @@
#ifndef BOOST_DETAIL_LWM_WIN32_NT_HPP_INCLUDED
#define BOOST_DETAIL_LWM_WIN32_NT_HPP_INCLUDED
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lwm_win32_nt.hpp
//
// Copyright (c) 2002, 2003 Peter Dimov
//
// 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.
//
// "No threads" version of lwm_win32.hpp; binary compatible but no-op.
//
namespace boost
{
namespace detail
{
class lightweight_mutex
{
private:
long l_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex(): l_(0)
{
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
explicit scoped_lock(lightweight_mutex &)
{
}
};
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_NT_HPP_INCLUDED

View File

@@ -1,555 +0,0 @@
#ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
#define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/shared_count.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
//
// 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 <boost/config.hpp>
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
#endif
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/detail/lightweight_mutex.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#include <boost/detail/quick_allocator.hpp>
#endif
#include <memory> // std::auto_ptr, std::allocator
#include <functional> // std::less
#include <exception> // std::exception
#include <new> // std::bad_alloc
#include <typeinfo> // std::type_info in get_deleter
#include <cstddef> // std::size_t
#ifdef __BORLANDC__
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
# pragma warn -8027 // Functions containing try are not expanded inline
#endif
namespace boost
{
// Debug hooks
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn);
void sp_array_constructor_hook(void * px);
void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn);
void sp_array_destructor_hook(void * px);
#endif
// The standard library that comes with Borland C++ 5.5.1
// defines std::exception and its members as having C calling
// convention (-pc). When the definition of bad_weak_ptr
// is compiled with -ps, the compiler issues an error.
// Hence, the temporary #pragma option -pc below. The version
// check is deliberately conservative.
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
# pragma option push -pc
#endif
class bad_weak_ptr: public std::exception
{
public:
virtual char const * what() const throw()
{
return "boost::bad_weak_ptr";
}
};
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
# pragma option pop
#endif
namespace detail
{
class sp_counted_base
{
private:
typedef detail::lightweight_mutex mutex_type;
public:
sp_counted_base(): use_count_(1), weak_count_(1)
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destruct() is called when weak_count_ drops to zero.
virtual void destruct() // nothrow
{
delete this;
}
virtual void * get_deleter(std::type_info const & ti) = 0;
void add_ref_copy()
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
++use_count_;
}
void add_ref_lock()
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
if(use_count_ == 0) boost::throw_exception(boost::bad_weak_ptr());
++use_count_;
}
void release() // nothrow
{
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
long new_use_count = --use_count_;
if(new_use_count != 0) return;
}
dispose();
weak_release();
}
void weak_add_ref() // nothrow
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
++weak_count_;
}
void weak_release() // nothrow
{
long new_weak_count;
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
new_weak_count = --weak_count_;
}
if(new_weak_count == 0)
{
destruct();
}
}
long use_count() const // nothrow
{
#if defined(BOOST_HAS_THREADS)
mutex_type::scoped_lock lock(mtx_);
#endif
return use_count_;
}
private:
sp_counted_base(sp_counted_base const &);
sp_counted_base & operator= (sp_counted_base const &);
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
#if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32)
mutable mutex_type mtx_;
#endif
};
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
{
boost::sp_scalar_constructor_hook(px, sizeof(T), pn);
}
template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
{
boost::sp_array_constructor_hook(px);
}
template<class P, class D> void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long)
{
}
template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
{
boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
}
template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
{
boost::sp_array_destructor_hook(px);
}
template<class P, class D> void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long)
{
}
#endif
//
// Borland's Codeguard trips up over the -Vx- option here:
//
#ifdef __CODEGUARD__
# pragma option push -Vx-
#endif
template<class P, class D> class sp_counted_base_impl: public sp_counted_base
{
private:
P ptr; // copy constructor must not throw
D del; // copy constructor must not throw
sp_counted_base_impl(sp_counted_base_impl const &);
sp_counted_base_impl & operator= (sp_counted_base_impl const &);
typedef sp_counted_base_impl<P, D> this_type;
public:
// pre: initial_use_count <= initial_weak_count, d(p) must not throw
sp_counted_base_impl(P p, D d): ptr(p), del(d)
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
detail::cbi_call_constructor_hook(this, p, d, 0);
#endif
}
virtual void dispose() // nothrow
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
detail::cbi_call_destructor_hook(this, ptr, del, 0);
#endif
del(ptr);
}
virtual void * get_deleter(std::type_info const & ti)
{
return ti == typeid(D)? &del: 0;
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new(std::size_t)
{
return std::allocator<this_type>().allocate(1, static_cast<this_type *>(0));
}
void operator delete(void * p)
{
std::allocator<this_type>().deallocate(static_cast<this_type *>(p), 1);
}
#endif
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
void * operator new(std::size_t)
{
return quick_allocator<this_type>::alloc();
}
void operator delete(void * p)
{
quick_allocator<this_type>::dealloc(p);
}
#endif
};
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int const shared_count_id = 0x2C35F101;
int const weak_count_id = 0x298C38A4;
#endif
class weak_count;
class shared_count
{
private:
sp_counted_base * pi_;
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int id_;
#endif
friend class weak_count;
public:
shared_count(): pi_(0) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
}
template<class P, class D> shared_count(P p, D d): pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = new sp_counted_base_impl<P, D>(p, d);
}
catch(...)
{
d(p); // delete p
throw;
}
#else
pi_ = new sp_counted_base_impl<P, D>(p, d);
if(pi_ == 0)
{
d(p); // delete p
boost::throw_exception(std::bad_alloc());
}
#endif
}
#ifndef BOOST_NO_AUTO_PTR
// auto_ptr<Y> is special cased to provide the strong guarantee
template<class Y>
explicit shared_count(std::auto_ptr<Y> & r): pi_(new sp_counted_base_impl< Y *, checked_deleter<Y> >(r.get(), checked_deleter<Y>()))
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
r.release();
}
#endif
~shared_count() // nothrow
{
if(pi_ != 0) pi_->release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
id_ = 0;
#endif
}
shared_count(shared_count const & r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if(pi_ != 0) pi_->add_ref_copy();
}
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
shared_count & operator= (shared_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if(tmp != 0) tmp->add_ref_copy();
if(pi_ != 0) pi_->release();
pi_ = tmp;
return *this;
}
void swap(shared_count & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const // nothrow
{
return pi_ != 0? pi_->use_count(): 0;
}
bool unique() const // nothrow
{
return use_count() == 1;
}
friend inline bool operator==(shared_count const & a, shared_count const & b)
{
return a.pi_ == b.pi_;
}
friend inline bool operator<(shared_count const & a, shared_count const & b)
{
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
}
void * get_deleter(std::type_info const & ti) const
{
return pi_? pi_->get_deleter(ti): 0;
}
};
#ifdef __CODEGUARD__
# pragma option pop
#endif
class weak_count
{
private:
sp_counted_base * pi_;
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int id_;
#endif
friend class shared_count;
public:
weak_count(): pi_(0) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
}
weak_count(shared_count const & r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if(pi_ != 0) pi_->weak_add_ref();
}
weak_count(weak_count const & r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if(pi_ != 0) pi_->weak_add_ref();
}
~weak_count() // nothrow
{
if(pi_ != 0) pi_->weak_release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
id_ = 0;
#endif
}
weak_count & operator= (shared_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if(tmp != 0) tmp->weak_add_ref();
if(pi_ != 0) pi_->weak_release();
pi_ = tmp;
return *this;
}
weak_count & operator= (weak_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if(tmp != 0) tmp->weak_add_ref();
if(pi_ != 0) pi_->weak_release();
pi_ = tmp;
return *this;
}
void swap(weak_count & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const // nothrow
{
return pi_ != 0? pi_->use_count(): 0;
}
friend inline bool operator==(weak_count const & a, weak_count const & b)
{
return a.pi_ == b.pi_;
}
friend inline bool operator<(weak_count const & a, weak_count const & b)
{
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
}
};
inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if(pi_ != 0)
{
pi_->add_ref_lock();
}
else
{
boost::throw_exception(boost::bad_weak_ptr());
}
}
} // namespace detail
} // namespace boost
#ifdef __BORLANDC__
# pragma warn .8027 // Functions containing try are not expanded inline
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
#endif
#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED

View File

@@ -0,0 +1,135 @@
#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_typeinfo.hpp
//
// Copyright 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined( BOOST_NO_TYPEID )
#include <boost/current_function.hpp>
#include <functional>
namespace boost
{
namespace detail
{
class sp_typeinfo
{
private:
sp_typeinfo( sp_typeinfo const& );
sp_typeinfo& operator=( sp_typeinfo const& );
char const * name_;
public:
explicit sp_typeinfo( char const * name ): name_( name )
{
}
bool operator==( sp_typeinfo const& rhs ) const
{
return this == &rhs;
}
bool operator!=( sp_typeinfo const& rhs ) const
{
return this != &rhs;
}
bool before( sp_typeinfo const& rhs ) const
{
return std::less< sp_typeinfo const* >()( this, &rhs );
}
char const* name() const
{
return name_;
}
};
template<class T> struct sp_typeid_
{
static sp_typeinfo ti_;
static char const * name()
{
return BOOST_CURRENT_FUNCTION;
}
};
#if defined(__SUNPRO_CC)
// see #4199, the Sun Studio compiler gets confused about static initialization
// constructor arguments. But an assignment works just fine.
template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
#else
template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
#endif
template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
{
};
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_<T>::ti_)
#else
#include <typeinfo>
namespace boost
{
namespace detail
{
#if defined( BOOST_NO_STD_TYPEINFO )
typedef ::type_info sp_typeinfo;
#else
typedef std::type_info sp_typeinfo;
#endif
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID(T) typeid(T)
#endif
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED

View File

@@ -6,63 +6,13 @@
//
// 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
//
#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
namespace boost
{
template<class T> class enable_shared_from_this
{
protected:
enable_shared_from_this()
{
}
enable_shared_from_this(enable_shared_from_this const &)
{
}
enable_shared_from_this & operator=(enable_shared_from_this const &)
{
return *this;
}
~enable_shared_from_this()
{
}
public:
shared_ptr<T> shared_from_this()
{
shared_ptr<T> p(_internal_weak_this);
BOOST_ASSERT(p.get() == this);
return p;
}
shared_ptr<T const> shared_from_this() const
{
shared_ptr<T const> p(_internal_weak_this);
BOOST_ASSERT(p.get() == this);
return p;
}
typedef T _internal_element_type; // for bcc 5.5.1
weak_ptr<_internal_element_type> _internal_weak_this;
};
} // namespace boost
#include <boost/smart_ptr/enable_shared_from_this.hpp>
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED

View File

@@ -1,12 +1,17 @@
// 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
#define GET_POINTER_DWA20021219_HPP
# include <memory>
#include <boost/config.hpp>
// In order to avoid circular dependencies with Boost.TR1
// we make sure that our include of <memory> doesn't try to
// pull in the TR1 headers: that's why we use this header
// rather than including <memory> directly:
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
namespace boost {
@@ -24,6 +29,19 @@ template<class T> T * get_pointer(std::auto_ptr<T> const& p)
return p.get();
}
#if !defined( BOOST_NO_CXX11_SMART_PTR )
template<class T> T * get_pointer( std::unique_ptr<T> const& p )
{
return p.get();
}
template<class T> T * get_pointer( std::shared_ptr<T> const& p )
{
return p.get();
}
#endif
} // namespace boost

View File

@@ -6,268 +6,13 @@
//
// 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->
#endif
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <functional> // for std::less
#include <iosfwd> // for std::basic_ostream
namespace boost
{
//
// intrusive_ptr
//
// A smart pointer that uses intrusive reference counting.
//
// Relies on unqualified calls to
//
// void intrusive_ptr_add_ref(T * p);
// void intrusive_ptr_release(T * p);
//
// (p != 0)
//
// The object is responsible for destroying itself.
//
template<class T> class intrusive_ptr
{
private:
typedef intrusive_ptr this_type;
public:
typedef T element_type;
intrusive_ptr(): p_(0)
{
}
intrusive_ptr(T * p, bool add_ref = true): p_(p)
{
if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_);
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
{
if(p_ != 0) intrusive_ptr_add_ref(p_);
}
#endif
intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
{
if(p_ != 0) intrusive_ptr_add_ref(p_);
}
~intrusive_ptr()
{
if(p_ != 0) intrusive_ptr_release(p_);
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
#endif
intrusive_ptr & operator=(intrusive_ptr const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
intrusive_ptr & operator=(T * rhs)
{
this_type(rhs).swap(*this);
return *this;
}
T * get() const
{
return p_;
}
T & operator*() const
{
return *p_;
}
T * operator->() const
{
return p_;
}
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
operator bool () const
{
return p_ != 0;
}
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
typedef T * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
{
return p_ == 0? 0: &this_type::get;
}
#else
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type () const
{
return p_ == 0? 0: &this_type::p_;
}
#endif
// operator! is a Borland-specific workaround
bool operator! () const
{
return p_ == 0;
}
void swap(intrusive_ptr & rhs)
{
T * tmp = p_;
p_ = rhs.p_;
rhs.p_ = tmp;
}
private:
T * p_;
};
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
{
return a.get() != b.get();
}
template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
{
return a.get() == b;
}
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
{
return a.get() != b;
}
template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
{
return a == b.get();
}
template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
{
return a != b.get();
}
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
// Resolve the ambiguity between our op!= and the one in rel_ops
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
{
return a.get() != b.get();
}
#endif
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
{
return std::less<T *>()(a.get(), b.get());
}
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
{
lhs.swap(rhs);
}
// mem_fn support
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
{
return p.get();
}
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
{
return static_cast<T *>(p.get());
}
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
{
return const_cast<T *>(p.get());
}
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
{
return dynamic_cast<T *>(p.get());
}
// operator<<
#if defined(__GNUC__) && (__GNUC__ < 3)
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
{
os << p.get();
return os;
}
#else
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
using std::basic_ostream;
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
# else
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
# endif
{
os << p.get();
return os;
}
#endif
} // namespace boost
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
#include <boost/smart_ptr/intrusive_ptr.hpp>
#endif // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,17 @@
#ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
#define BOOST_MAKE_SHARED_HPP_INCLUDED
// make_shared.hpp
//
// Copyright (c) 2007, 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://www.boost.org/libs/smart_ptr/make_shared.html
// for documentation.
#include <boost/smart_ptr/make_shared.hpp>
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED

View File

@@ -0,0 +1,53 @@
#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
#define BOOST_MEMORY_ORDER_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/memory_order.hpp
//
// Defines enum boost::memory_order per the C++0x working draft
//
// Copyright (c) 2008, 2009 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
namespace boost
{
//
// Enum values are chosen so that code that needs to insert
// a trailing fence for acquire semantics can use a single
// test such as:
//
// if( mo & memory_order_acquire ) { ...fence... }
//
// For leading fences one can use:
//
// if( mo & memory_order_release ) { ...fence... }
//
// Architectures such as Alpha that need a fence on consume
// can use:
//
// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... }
//
enum memory_order
{
memory_order_relaxed = 0,
memory_order_acquire = 1,
memory_order_release = 2,
memory_order_acq_rel = 3, // acquire | release
memory_order_seq_cst = 7, // acq_rel | 4
memory_order_consume = 8
};
} // namespace boost
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED

View File

@@ -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,133 +4,13 @@
// (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
//
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/config.hpp> // in case ptrdiff_t not in std
#include <boost/detail/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t
namespace boost
{
// Debug hooks
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_array_constructor_hook(void * p);
void sp_array_destructor_hook(void * p);
#endif
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
// is guaranteed, either on destruction of the scoped_array or via an explicit
// reset(). Use shared_array or std::vector if your needs are more complex.
template<class T> class scoped_array // noncopyable
{
private:
T * ptr;
scoped_array(scoped_array const &);
scoped_array & operator=(scoped_array const &);
typedef scoped_array<T> this_type;
public:
typedef T element_type;
explicit scoped_array(T * p = 0) : ptr(p) // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_array_constructor_hook(ptr);
#endif
}
~scoped_array() // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_array_destructor_hook(ptr);
#endif
boost::checked_array_delete(ptr);
}
void reset(T * p = 0) // never throws
{
BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors
this_type(p).swap(*this);
}
T & operator[](std::ptrdiff_t i) const // never throws
{
BOOST_ASSERT(ptr != 0);
BOOST_ASSERT(i >= 0);
return ptr[i];
}
T * get() const // never throws
{
return ptr;
}
// implicit conversion to "bool"
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
operator bool () const
{
return ptr != 0;
}
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
typedef T * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
{
return ptr == 0? 0: &this_type::get;
}
#else
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const // never throws
{
return ptr == 0? 0: &this_type::ptr;
}
#endif
bool operator! () const // never throws
{
return ptr == 0;
}
void swap(scoped_array & b) // never throws
{
T * tmp = b.ptr;
b.ptr = ptr;
ptr = tmp;
}
};
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
{
a.swap(b);
}
} // namespace boost
#include <boost/smart_ptr/scoped_array.hpp>
#endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED

View File

@@ -4,155 +4,13 @@
// (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
#endif
namespace boost
{
// Debug hooks
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_scalar_constructor_hook(void * p);
void sp_scalar_destructor_hook(void * p);
#endif
// scoped_ptr mimics a built-in pointer except that it guarantees deletion
// of the object pointed to, either on destruction of the scoped_ptr or via
// an explicit reset(). scoped_ptr is a simple solution for simple needs;
// use shared_ptr or std::auto_ptr if your needs are more complex.
template<class T> class scoped_ptr // noncopyable
{
private:
T * ptr;
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
typedef scoped_ptr<T> this_type;
public:
typedef T element_type;
explicit scoped_ptr(T * p = 0): ptr(p) // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook(ptr);
#endif
}
#ifndef BOOST_NO_AUTO_PTR
explicit scoped_ptr(std::auto_ptr<T> p): ptr(p.release()) // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook(ptr);
#endif
}
#endif
~scoped_ptr() // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook(ptr);
#endif
boost::checked_delete(ptr);
}
void reset(T * p = 0) // never throws
{
BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors
this_type(p).swap(*this);
}
T & operator*() const // never throws
{
BOOST_ASSERT(ptr != 0);
return *ptr;
}
T * operator->() const // never throws
{
BOOST_ASSERT(ptr != 0);
return ptr;
}
T * get() const // never throws
{
return ptr;
}
// implicit conversion to "bool"
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
operator bool () const
{
return ptr != 0;
}
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
typedef T * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
{
return ptr == 0? 0: &this_type::get;
}
#else
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const // never throws
{
return ptr == 0? 0: &this_type::ptr;
}
#endif
bool operator! () const // never throws
{
return ptr == 0;
}
void swap(scoped_ptr & b) // never throws
{
T * tmp = b.ptr;
b.ptr = ptr;
ptr = tmp;
}
};
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
{
a.swap(b);
}
// get_pointer(p) is a generic way to say p.get()
template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
{
return p.get();
}
} // namespace boost
#include <boost/smart_ptr/scoped_ptr.hpp>
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED

View File

@@ -7,170 +7,13 @@
// (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.
//
#include <boost/config.hpp> // for broken compiler workarounds
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/detail/shared_array_nmt.hpp>
#else
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/detail/shared_count.hpp>
#include <boost/detail/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t
#include <algorithm> // for std::swap
#include <functional> // for std::less
namespace boost
{
//
// shared_array
//
// shared_array extends shared_ptr to arrays.
// The array pointed to is deleted when the last shared_array pointing to it
// is destroyed or reset.
//
template<class T> class shared_array
{
private:
// Borland 5.5.1 specific workarounds
typedef checked_array_deleter<T> deleter;
typedef shared_array<T> this_type;
public:
typedef T element_type;
explicit shared_array(T * p = 0): px(p), pn(p, deleter())
{
}
//
// Requirements: D's copy constructor must not throw
//
// shared_array will release p by calling d(p)
//
template<class D> shared_array(T * p, D d): px(p), pn(p, d)
{
}
// generated copy constructor, assignment, destructor are fine
void reset(T * p = 0)
{
BOOST_ASSERT(p == 0 || p != px);
this_type(p).swap(*this);
}
template <class D> void reset(T * p, D d)
{
this_type(p, d).swap(*this);
}
T & operator[] (std::ptrdiff_t i) const // never throws
{
BOOST_ASSERT(px != 0);
BOOST_ASSERT(i >= 0);
return px[i];
}
T * get() const // never throws
{
return px;
}
// implicit conversion to "bool"
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
operator bool () const
{
return px != 0;
}
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
typedef T * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
{
return px == 0? 0: &this_type::get;
}
#else
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const // never throws
{
return px == 0? 0: &this_type::px;
}
#endif
bool operator! () const // never throws
{
return px == 0;
}
bool unique() const // never throws
{
return pn.unique();
}
long use_count() const // never throws
{
return pn.use_count();
}
void swap(shared_array<T> & other) // never throws
{
std::swap(px, other.px);
pn.swap(other.pn);
}
private:
T * px; // contained pointer
detail::shared_count pn; // reference counter
}; // shared_array
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
{
return a.get() == b.get();
}
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
{
return a.get() != b.get();
}
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
{
return std::less<T*>()(a.get(), b.get());
}
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
{
a.swap(b);
}
} // namespace boost
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/smart_ptr/shared_array.hpp>
#endif // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED

View File

@@ -5,470 +5,15 @@
// 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.
//
#include <boost/config.hpp> // for broken compiler workarounds
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/detail/shared_ptr_nmt.hpp>
#else
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/detail/shared_count.hpp>
#include <boost/detail/workaround.hpp>
#include <memory> // for std::auto_ptr
#include <algorithm> // for std::swap
#include <functional> // for std::less
#include <typeinfo> // for std::bad_cast
#include <iosfwd> // for std::basic_ostream
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
# pragma warning(push)
# pragma warning(disable:4284) // odd return type for operator->
#endif
namespace boost
{
template<class T> class weak_ptr;
template<class T> class enable_shared_from_this;
namespace detail
{
struct static_cast_tag {};
struct const_cast_tag {};
struct dynamic_cast_tag {};
struct polymorphic_cast_tag {};
template<class T> struct shared_ptr_traits
{
typedef T & reference;
};
template<> struct shared_ptr_traits<void>
{
typedef void reference;
};
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
template<> struct shared_ptr_traits<void const>
{
typedef void reference;
};
template<> struct shared_ptr_traits<void volatile>
{
typedef void reference;
};
template<> struct shared_ptr_traits<void const volatile>
{
typedef void reference;
};
#endif
// enable_shared_from_this support
template<class T, class Y> void sp_enable_shared_from_this(boost::enable_shared_from_this<T> * pe, Y * px, shared_count const & pn)
{
if(pe != 0) pe->_internal_weak_this._internal_assign(px, pn);
}
inline void sp_enable_shared_from_this(void const volatile *, void const volatile *, shared_count const &)
{
}
} // namespace detail
//
// shared_ptr
//
// An enhanced relative of scoped_ptr with reference counted copy semantics.
// The object pointed to is deleted when the last shared_ptr pointing to it
// is destroyed or reset.
//
template<class T> class shared_ptr
{
private:
// Borland 5.5.1 specific workaround
typedef shared_ptr<T> this_type;
public:
typedef T element_type;
typedef T value_type;
typedef T * pointer;
typedef typename detail::shared_ptr_traits<T>::reference reference;
shared_ptr(): px(0), pn() // never throws in 1.30+
{
}
template<class Y>
explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete
{
detail::sp_enable_shared_from_this(p, p, pn);
}
//
// Requirements: D's copy constructor must not throw
//
// shared_ptr will release p by calling d(p)
//
template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
{
detail::sp_enable_shared_from_this(p, p, pn);
}
// generated copy constructor, assignment, destructor are fine...
// except that Borland C++ has a bug, and g++ with -Wsynth warns
#if defined(__BORLANDC__) || defined(__GNUC__)
shared_ptr & operator=(shared_ptr const & r) // never throws
{
px = r.px;
pn = r.pn; // shared_count::op= doesn't throw
return *this;
}
#endif
template<class Y>
explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
{
// it is now safe to copy r.px, as pn(r.pn) did not throw
px = r.px;
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
{
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
{
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
{
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
{
if(px == 0) // need to allocate new counter -- the cast failed
{
pn = detail::shared_count();
}
}
template<class Y>
shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
{
if(px == 0)
{
boost::throw_exception(std::bad_cast());
}
}
#ifndef BOOST_NO_AUTO_PTR
template<class Y>
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
{
Y * tmp = r.get();
pn = detail::shared_count(r);
detail::sp_enable_shared_from_this(tmp, tmp, pn);
}
#endif
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
template<class Y>
shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
{
px = r.px;
pn = r.pn; // shared_count::op= doesn't throw
return *this;
}
#endif
#ifndef BOOST_NO_AUTO_PTR
template<class Y>
shared_ptr & operator=(std::auto_ptr<Y> & r)
{
this_type(r).swap(*this);
return *this;
}
#endif
void reset() // never throws in 1.30+
{
this_type().swap(*this);
}
template<class Y> void reset(Y * p) // Y must be complete
{
BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
this_type(p).swap(*this);
}
template<class Y, class D> void reset(Y * p, D d)
{
this_type(p, d).swap(*this);
}
reference operator* () const // never throws
{
BOOST_ASSERT(px != 0);
return *px;
}
T * operator-> () const // never throws
{
BOOST_ASSERT(px != 0);
return px;
}
T * get() const // never throws
{
return px;
}
// implicit conversion to "bool"
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
operator bool () const
{
return px != 0;
}
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
typedef T * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
{
return px == 0? 0: &this_type::get;
}
#else
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const // never throws
{
return px == 0? 0: &this_type::px;
}
#endif
// operator! is redundant, but some compilers need it
bool operator! () const // never throws
{
return px == 0;
}
bool unique() const // never throws
{
return pn.unique();
}
long use_count() const // never throws
{
return pn.use_count();
}
void swap(shared_ptr<T> & other) // never throws
{
std::swap(px, other.px);
pn.swap(other.pn);
}
template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
{
return pn < rhs.pn;
}
void * _internal_get_deleter(std::type_info const & ti) const
{
return pn.get_deleter(ti);
}
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
private:
template<class Y> friend class shared_ptr;
template<class Y> friend class weak_ptr;
#endif
T * px; // contained pointer
detail::shared_count pn; // reference counter
}; // shared_ptr
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
{
return a.get() != b.get();
}
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
// Resolve the ambiguity between our op!= and the one in rel_ops
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
{
return a.get() != b.get();
}
#endif
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
{
return a._internal_less(b);
}
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
{
a.swap(b);
}
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::static_cast_tag());
}
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::const_cast_tag());
}
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::dynamic_cast_tag());
}
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::static_cast_tag());
}
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::dynamic_cast_tag());
}
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::polymorphic_cast_tag());
}
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
{
BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
return shared_static_cast<T>(r);
}
// get_pointer() enables boost::mem_fn to recognize shared_ptr
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
{
return p.get();
}
// operator<<
#if defined(__GNUC__) && (__GNUC__ < 3)
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
{
os << p.get();
return os;
}
#else
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
using std::basic_ostream;
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
# else
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
# endif
{
os << p.get();
return os;
}
#endif
// get_deleter (experimental)
#if (defined(__GNUC__) && (__GNUC__ < 3)) || (defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238))
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
// apparently EDG 2.38 also doesn't accept it
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
{
void const * q = p._internal_get_deleter(typeid(D));
return const_cast<D *>(static_cast<D const *>(q));
}
#else
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
{
return static_cast<D *>(p._internal_get_deleter(typeid(D)));
}
#endif
} // namespace boost
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/smart_ptr/shared_ptr.hpp>
#endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED

View File

@@ -1,16 +1,15 @@
#ifndef BOOST_SMART_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_HPP_INCLUDED
//
// smart_ptr.hpp
//
// For convenience, this header includes the rest of the smart
// pointer library headers.
//
// Copyright (c) 1998-2002 boost.org
// 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.
// 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
//
@@ -26,4 +25,7 @@
# include <boost/weak_ptr.hpp>
# include <boost/intrusive_ptr.hpp>
# include <boost/enable_shared_from_this.hpp>
# include <boost/make_shared.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,119 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/atomic_count.hpp - thread/SMP safe reference counter
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// typedef <implementation-defined> boost::detail::atomic_count;
//
// atomic_count a(n);
//
// (n is convertible to long)
//
// Effects: Constructs an atomic_count with an initial value of n
//
// a;
//
// Returns: (long) the current value of a
//
// ++a;
//
// Effects: Atomically increments the value of a
// Returns: (long) the new value of a
//
// --a;
//
// Effects: Atomically decrements the value of a
// Returns: (long) the new value of a
//
// Important note: when --a returns zero, it must act as a
// read memory barrier (RMB); i.e. the calling thread must
// have a synchronized view of the memory
//
// On Intel IA-32 (x86) memory is always synchronized, so this
// is not a problem.
//
// On many architectures the atomic instructions already act as
// a memory barrier.
//
// This property is necessary for proper reference counting, since
// a thread can update the contents of a shared object, then
// release its reference, and another thread may immediately
// release the last reference causing object destruction.
//
// The destructor needs to have a synchronized view of the
// object to perform proper cleanup.
//
// Original example by Alexander Terekhov:
//
// Given:
//
// - a mutable shared object OBJ;
// - two threads THREAD1 and THREAD2 each holding
// a private smart_ptr object pointing to that OBJ.
//
// t1: THREAD1 updates OBJ (thread-safe via some synchronization)
// and a few cycles later (after "unlock") destroys smart_ptr;
//
// t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization
// with respect to shared mutable object OBJ; OBJ destructors
// are called driven by smart_ptr interface...
//
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#ifndef BOOST_HAS_THREADS
namespace boost
{
namespace detail
{
typedef long atomic_count;
}
}
#elif defined(BOOST_AC_USE_PTHREADS)
# include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# define BOOST_AC_USE_PTHREADS
# include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error
#error Unrecognized threading platform
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED

View File

@@ -0,0 +1,72 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
//
// boost/detail/atomic_count_gcc.hpp
//
// atomic_count for GNU libstdc++ v3
//
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2002 Lars Gullik Bj<42>nnes <larsbj@lyx.org>
// Copyright 2003-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
# include <ext/atomicity.h>
#else
# include <bits/atomicity.h>
#endif
namespace boost
{
namespace detail
{
#if defined(__GLIBCXX__) // g++ 3.4+
using __gnu_cxx::__atomic_add;
using __gnu_cxx::__exchange_and_add;
#endif
class atomic_count
{
public:
explicit atomic_count( long v ) : value_( v ) {}
long operator++()
{
return __exchange_and_add( &value_, +1 ) + 1;
}
long operator--()
{
return __exchange_and_add( &value_, -1 ) - 1;
}
operator long() const
{
return __exchange_and_add( &value_, 0 );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
mutable _Atomic_word value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED

View File

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

View File

@@ -1,15 +1,14 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
//
// boost/detail/atomic_count_pthreads.hpp
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//
// 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>
@@ -63,10 +62,10 @@ public:
pthread_mutex_destroy(&mutex_);
}
void operator++()
long operator++()
{
scoped_lock lock(mutex_);
++value_;
return ++value_;
}
long operator--()
@@ -94,4 +93,4 @@ private:
} // namespace boost
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED

View File

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

View File

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

View File

@@ -0,0 +1,63 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/atomic_count_win32.hpp
//
// Copyright (c) 2001-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/interlocked.hpp>
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
return BOOST_INTERLOCKED_INCREMENT( &value_ );
}
long operator--()
{
return BOOST_INTERLOCKED_DECREMENT( &value_ );
}
operator long() const
{
return static_cast<long const volatile &>( value_ );
}
private:
atomic_count( atomic_count const & );
atomic_count & operator=( atomic_count const & );
long value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED

View File

@@ -0,0 +1,42 @@
#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lightweight_mutex.hpp - lightweight mutex
//
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// typedef <unspecified> boost::detail::lightweight_mutex;
//
// boost::detail::lightweight_mutex is a header-only implementation of
// a subset of the Mutex concept requirements:
//
// http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
//
// It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
//
#include <boost/config.hpp>
#if !defined(BOOST_HAS_THREADS)
# include <boost/smart_ptr/detail/lwm_nop.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# include <boost/smart_ptr/detail/lwm_pthreads.hpp>
#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/lwm_win32_cs.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error
# error Unrecognized threading platform
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED

View File

@@ -0,0 +1,37 @@
#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lwm_nop.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
namespace boost
{
namespace detail
{
class lightweight_mutex
{
public:
typedef lightweight_mutex scoped_lock;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
#define BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -12,12 +12,12 @@
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/assert.hpp>
#include <pthread.h>
namespace boost
@@ -43,15 +43,15 @@ public:
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
#if defined(__hpux) && defined(_DECTHREADS_)
pthread_mutex_init(&m_, pthread_mutexattr_default);
BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
#else
pthread_mutex_init(&m_, 0);
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
#endif
}
~lightweight_mutex()
{
pthread_mutex_destroy(&m_);
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
}
class scoped_lock;
@@ -70,12 +70,12 @@ public:
scoped_lock(lightweight_mutex & m): m_(m.m_)
{
pthread_mutex_lock(&m_);
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
}
~scoped_lock()
{
pthread_mutex_unlock(&m_);
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
}
};
};
@@ -84,4 +84,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
// MS compatible compilers support #pragma once
@@ -12,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
@@ -30,7 +29,7 @@ namespace detail
#ifndef BOOST_USE_WINDOWS_H
struct CRITICAL_SECTION
struct critical_section
{
struct critical_section_debug * DebugInfo;
long LockCount;
@@ -44,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
@@ -55,7 +58,7 @@ class lightweight_mutex
{
private:
CRITICAL_SECTION cs_;
critical_section cs_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
@@ -102,4 +105,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED

View File

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

View File

@@ -0,0 +1,63 @@
// This header intentionally has no include guards.
//
// Copyright (c) 2001-2009, 2012 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )
explicit operator bool () const BOOST_NOEXCEPT
{
return px != 0;
}
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
operator bool () const BOOST_NOEXCEPT
{
return px != 0;
}
#elif defined( _MANAGED )
static void unspecified_bool( this_type*** )
{
}
typedef void (*unspecified_bool_type)( this_type*** );
operator unspecified_bool_type() const BOOST_NOEXCEPT
{
return px == 0? 0: unspecified_bool;
}
#elif \
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
typedef element_type * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const BOOST_NOEXCEPT
{
return px == 0? 0: &this_type::get;
}
#else
typedef element_type * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const BOOST_NOEXCEPT
{
return px == 0? 0: &this_type::px;
}
#endif
// operator! is redundant, but some compilers need it
bool operator! () const BOOST_NOEXCEPT
{
return px == 0;
}

View File

@@ -0,0 +1,199 @@
#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/quick_allocator.hpp
//
// Copyright (c) 2003 David Abrahams
// Copyright (c) 2003 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <new> // ::operator new, ::operator delete
#include <cstddef> // std::size_t
namespace boost
{
namespace detail
{
template<unsigned size, unsigned align_> union freeblock
{
typedef typename boost::type_with_alignment<align_>::type aligner_type;
aligner_type aligner;
char bytes[size];
freeblock * next;
};
template<unsigned size, unsigned align_> struct allocator_impl
{
typedef freeblock<size, align_> block;
// It may seem odd to use such small pages.
//
// However, on a typical Windows implementation that uses
// the OS allocator, "normal size" pages interact with the
// "ordinary" operator new, slowing it down dramatically.
//
// 512 byte pages are handled by the small object allocator,
// and don't interfere with ::new.
//
// The other alternative is to use much bigger pages (1M.)
//
// It is surprisingly easy to hit pathological behavior by
// varying the page size. g++ 2.96 on Red Hat Linux 7.2,
// for example, passionately dislikes 496. 512 seems OK.
#if defined(BOOST_QA_PAGE_SIZE)
enum { items_per_page = BOOST_QA_PAGE_SIZE / size };
#else
enum { items_per_page = 512 / size }; // 1048560 / size
#endif
#ifdef BOOST_HAS_THREADS
static lightweight_mutex & mutex()
{
static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
return *pm;
}
static lightweight_mutex * mutex_init;
#endif
static block * free;
static block * page;
static unsigned last;
static inline void * alloc()
{
#ifdef BOOST_HAS_THREADS
lightweight_mutex::scoped_lock lock( mutex() );
#endif
if(block * x = free)
{
free = x->next;
return x;
}
else
{
if(last == items_per_page)
{
// "Listen to me carefully: there is no memory leak"
// -- Scott Meyers, Eff C++ 2nd Ed Item 10
page = ::new block[items_per_page];
last = 0;
}
return &page[last++];
}
}
static inline void * alloc(std::size_t n)
{
if(n != size) // class-specific new called for a derived object
{
return ::operator new(n);
}
else
{
#ifdef BOOST_HAS_THREADS
lightweight_mutex::scoped_lock lock( mutex() );
#endif
if(block * x = free)
{
free = x->next;
return x;
}
else
{
if(last == items_per_page)
{
page = ::new block[items_per_page];
last = 0;
}
return &page[last++];
}
}
}
static inline void dealloc(void * pv)
{
if(pv != 0) // 18.4.1.1/13
{
#ifdef BOOST_HAS_THREADS
lightweight_mutex::scoped_lock lock( mutex() );
#endif
block * pb = static_cast<block *>(pv);
pb->next = free;
free = pb;
}
}
static inline void dealloc(void * pv, std::size_t n)
{
if(n != size) // class-specific delete called for a derived object
{
::operator delete(pv);
}
else if(pv != 0) // 18.4.1.1/13
{
#ifdef BOOST_HAS_THREADS
lightweight_mutex::scoped_lock lock( mutex() );
#endif
block * pb = static_cast<block *>(pv);
pb->next = free;
free = pb;
}
}
};
#ifdef BOOST_HAS_THREADS
template<unsigned size, unsigned align_>
lightweight_mutex * allocator_impl<size, align_>::mutex_init = &allocator_impl<size, align_>::mutex();
#endif
template<unsigned size, unsigned align_>
freeblock<size, align_> * allocator_impl<size, align_>::free = 0;
template<unsigned size, unsigned align_>
freeblock<size, align_> * allocator_impl<size, align_>::page = 0;
template<unsigned size, unsigned align_>
unsigned allocator_impl<size, align_>::last = allocator_impl<size, align_>::items_per_page;
template<class T>
struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of<T>::value >
{
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED

View File

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

View File

@@ -0,0 +1,603 @@
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/shared_count.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifdef __BORLANDC__
# pragma warn -8027 // Functions containing try are not expanded inline
#endif
#include <boost/config.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/bad_weak_ptr.hpp>
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
#include <boost/detail/workaround.hpp>
// In order to avoid circular dependencies with Boost.TR1
// we make sure that our include of <memory> doesn't try to
// pull in the TR1 headers: that's why we use this header
// rather than including <memory> directly:
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
#include <functional> // std::less
#ifdef BOOST_NO_EXCEPTIONS
# include <new> // std::bad_alloc
#endif
#if !defined( BOOST_NO_CXX11_SMART_PTR )
# include <boost/utility/addressof.hpp>
#endif
namespace boost
{
namespace detail
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int const shared_count_id = 0x2C35F101;
int const weak_count_id = 0x298C38A4;
#endif
struct sp_nothrow_tag {};
template< class D > struct sp_inplace_tag
{
};
#if !defined( BOOST_NO_CXX11_SMART_PTR )
template< class T > class sp_reference_wrapper
{
public:
explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
{
}
template< class Y > void operator()( Y * p ) const
{
(*t_)( p );
}
private:
T * t_;
};
template< class D > struct sp_convert_reference
{
typedef D type;
};
template< class D > struct sp_convert_reference< D& >
{
typedef sp_reference_wrapper< D > type;
};
#endif
class weak_count;
class shared_count
{
private:
sp_counted_base * pi_;
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int id_;
#endif
friend class weak_count;
public:
shared_count(): pi_(0) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
}
template<class Y> explicit shared_count( Y * p ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = new sp_counted_impl_p<Y>( p );
}
catch(...)
{
boost::checked_delete( p );
throw;
}
#else
pi_ = new sp_counted_impl_p<Y>( p );
if( pi_ == 0 )
{
boost::checked_delete( p );
boost::throw_exception( std::bad_alloc() );
}
#endif
}
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
#else
template<class P, class D> shared_count( P p, D d ): pi_(0)
#endif
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
typedef Y* P;
#endif
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = new sp_counted_impl_pd<P, D>(p, d);
}
catch(...)
{
d(p); // delete p
throw;
}
#else
pi_ = new sp_counted_impl_pd<P, D>(p, d);
if(pi_ == 0)
{
d(p); // delete p
boost::throw_exception(std::bad_alloc());
}
#endif
}
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = new sp_counted_impl_pd< P, D >( p );
}
catch( ... )
{
D::operator_fn( p ); // delete p
throw;
}
#else
pi_ = new sp_counted_impl_pd< P, D >( p );
if( pi_ == 0 )
{
D::operator_fn( p ); // delete p
boost::throw_exception( std::bad_alloc() );
}
#endif // #ifndef BOOST_NO_EXCEPTIONS
}
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
typedef sp_counted_impl_pda<P, D, A> impl_type;
typedef typename A::template rebind< impl_type >::other A2;
A2 a2( a );
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
}
catch(...)
{
d( p );
if( pi_ != 0 )
{
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
}
throw;
}
#else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
if( pi_ != 0 )
{
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
}
else
{
d( p );
boost::throw_exception( std::bad_alloc() );
}
#endif
}
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
typedef sp_counted_impl_pda< P, D, A > impl_type;
typedef typename A::template rebind< impl_type >::other A2;
A2 a2( a );
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
new( static_cast< void* >( pi_ ) ) impl_type( p, a );
}
catch(...)
{
D::operator_fn( p );
if( pi_ != 0 )
{
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
}
throw;
}
#else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
if( pi_ != 0 )
{
new( static_cast< void* >( pi_ ) ) impl_type( p, a );
}
else
{
D::operator_fn( p );
boost::throw_exception( std::bad_alloc() );
}
#endif // #ifndef BOOST_NO_EXCEPTIONS
}
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
#ifndef BOOST_NO_AUTO_PTR
// auto_ptr<Y> is special cased to provide the strong guarantee
template<class Y>
explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#ifdef BOOST_NO_EXCEPTIONS
if( pi_ == 0 )
{
boost::throw_exception(std::bad_alloc());
}
#endif
r.release();
}
#endif
#if !defined( BOOST_NO_CXX11_SMART_PTR )
template<class Y, class D>
explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
typedef typename sp_convert_reference<D>::type D2;
D2 d2( r.get_deleter() );
pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
#ifdef BOOST_NO_EXCEPTIONS
if( pi_ == 0 )
{
boost::throw_exception( std::bad_alloc() );
}
#endif
r.release();
}
#endif
~shared_count() // nothrow
{
if( pi_ != 0 ) pi_->release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
id_ = 0;
#endif
}
shared_count(shared_count const & r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if( pi_ != 0 ) pi_->add_ref_copy();
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
shared_count(shared_count && r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
r.pi_ = 0;
}
#endif
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
shared_count & operator= (shared_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if( tmp != pi_ )
{
if( tmp != 0 ) tmp->add_ref_copy();
if( pi_ != 0 ) pi_->release();
pi_ = tmp;
}
return *this;
}
void swap(shared_count & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const // nothrow
{
return pi_ != 0? pi_->use_count(): 0;
}
bool unique() const // nothrow
{
return use_count() == 1;
}
bool empty() const // nothrow
{
return pi_ == 0;
}
friend inline bool operator==(shared_count const & a, shared_count const & b)
{
return a.pi_ == b.pi_;
}
friend inline bool operator<(shared_count const & a, shared_count const & b)
{
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
}
void * get_deleter( sp_typeinfo const & ti ) const
{
return pi_? pi_->get_deleter( ti ): 0;
}
void * get_untyped_deleter() const
{
return pi_? pi_->get_untyped_deleter(): 0;
}
};
class weak_count
{
private:
sp_counted_base * pi_;
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
int id_;
#endif
friend class shared_count;
public:
weak_count(): pi_(0) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
}
weak_count(shared_count const & r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
if(pi_ != 0) pi_->weak_add_ref();
}
weak_count(weak_count const & r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
if(pi_ != 0) pi_->weak_add_ref();
}
// Move support
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
weak_count(weak_count && r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
r.pi_ = 0;
}
#endif
~weak_count() // nothrow
{
if(pi_ != 0) pi_->weak_release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
id_ = 0;
#endif
}
weak_count & operator= (shared_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if( tmp != pi_ )
{
if(tmp != 0) tmp->weak_add_ref();
if(pi_ != 0) pi_->weak_release();
pi_ = tmp;
}
return *this;
}
weak_count & operator= (weak_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
if( tmp != pi_ )
{
if(tmp != 0) tmp->weak_add_ref();
if(pi_ != 0) pi_->weak_release();
pi_ = tmp;
}
return *this;
}
void swap(weak_count & r) // nothrow
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const // nothrow
{
return pi_ != 0? pi_->use_count(): 0;
}
bool empty() const // nothrow
{
return pi_ == 0;
}
friend inline bool operator==(weak_count const & a, weak_count const & b)
{
return a.pi_ == b.pi_;
}
friend inline bool operator<(weak_count const & a, weak_count const & b)
{
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
}
};
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if( pi_ == 0 || !pi_->add_ref_lock() )
{
boost::throw_exception( boost::bad_weak_ptr() );
}
}
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
if( pi_ != 0 && !pi_->add_ref_lock() )
{
pi_ = 0;
}
}
} // namespace detail
} // namespace boost
#ifdef __BORLANDC__
# pragma warn .8027 // Functions containing try are not expanded inline
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED

View File

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

View File

@@ -0,0 +1,91 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_convertible.hpp
//
// Copyright 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
namespace boost
{
namespace detail
{
template< class Y, class T > struct sp_convertible
{
typedef char (&yes) [1];
typedef char (&no) [2];
static yes f( T* );
static no f( ... );
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
};
template< class Y, class T > struct sp_convertible< Y, T[] >
{
enum _vt { value = false };
};
template< class Y, class T > struct sp_convertible< Y[], T[] >
{
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
};
template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
{
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
};
struct sp_empty
{
};
template< bool > struct sp_enable_if_convertible_impl;
template<> struct sp_enable_if_convertible_impl<true>
{
typedef sp_empty type;
};
template<> struct sp_enable_if_convertible_impl<false>
{
};
template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
{
};
} // namespace detail
} // namespace boost
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED

View File

@@ -0,0 +1,79 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base.hpp
//
// Copyright 2005, 2006 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#if defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_USE_SPINLOCK )
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
#elif defined( BOOST_SP_USE_PTHREADS )
# include <boost/smart_ptr/detail/sp_counted_base_pt.hpp>
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( __SNC__ )
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
#elif defined(__HP_aCC) && defined(__ia64)
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
#elif defined( __IBMCPP__ ) && defined( __powerpc )
# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
#elif defined( _AIX )
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
#elif !defined( BOOST_HAS_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#else
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED

View File

@@ -0,0 +1,151 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
//
// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
//
// Copyright 2007 Baruch Zilber
// Copyright 2007 Boris Gubenko
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <machine/sys/inline.h>
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
if (1 == r)
{
_Asm_mf();
}
return r - 1;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int v = *pw;
for (;;)
{
if (0 == v)
{
return 0;
}
_Asm_mov_to_ar(_AREG_CCV,
v,
(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
if (r == v)
{
return r + 1;
}
v = r;
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED

View File

@@ -0,0 +1,143 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
//
// detail/sp_counted_base_aix.hpp
// based on: detail/sp_counted_base_w32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
// Copyright 2006 Michael van der Westhuizen
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <builtins.h>
#include <sys/atomic_op.h>
namespace boost
{
namespace detail
{
inline void atomic_increment( int32_t* pw )
{
// ++*pw;
fetch_and_add( pw, 1 );
}
inline int32_t atomic_decrement( int32_t * pw )
{
// return --*pw;
int32_t originalValue;
__lwsync();
originalValue = fetch_and_add( pw, -1 );
__isync();
return (originalValue - 1);
}
inline int32_t atomic_conditional_increment( int32_t * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int32_t tmp = fetch_and_add( pw, 0 );
for( ;; )
{
if( tmp == 0 ) return 0;
if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int32_t use_count_; // #shared
int32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED

View File

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

View File

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

View File

@@ -0,0 +1,158 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
//
// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2006 Peter Dimov
// Copyright 2005 Ben Hutchings
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
int tmp;
// No barrier is required here but fetchadd always has an acquire or
// release barrier associated with it. We choose release as it should be
// cheaper.
__asm__ ("fetchadd4.rel %0=%1,1" :
"=r"(tmp), "=m"(*pw) :
"m"( *pw ));
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int rv;
__asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
" cmp.eq p7,p0=1,%0 ;; \n"
"(p7) ld4.acq %0=%1 " :
"=&r"(rv), "=m"(*pw) :
"m"( *pw ) :
"p7");
return rv;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv, tmp, tmp2;
__asm__ ("0: ld4 %0=%3 ;; \n"
" cmp.eq p7,p0=0,%0 ;; \n"
"(p7) br.cond.spnt 1f \n"
" mov ar.ccv=%0 \n"
" add %1=1,%0 ;; \n"
" cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
" cmp.ne p7,p0=%0,%2 ;; \n"
"(p7) br.cond.spnt 0b \n"
" mov %0=%1 ;; \n"
"1:" :
"=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
"m"( *pw ) :
"ar.ccv", "p7");
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED

View File

@@ -0,0 +1,182 @@
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
//
// Copyright (c) 2009, Spirent Communications, Inc.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
namespace boost
{
namespace detail
{
inline void atomic_increment( int * pw )
{
// ++*pw;
int tmp;
__asm__ __volatile__
(
"0:\n\t"
".set push\n\t"
".set mips2\n\t"
"ll %0, %1\n\t"
"addiu %0, 1\n\t"
"sc %0, %1\n\t"
".set pop\n\t"
"beqz %0, 0b":
"=&r"( tmp ), "=m"( *pw ):
"m"( *pw )
);
}
inline int atomic_decrement( int * pw )
{
// return --*pw;
int rv, tmp;
__asm__ __volatile__
(
"0:\n\t"
".set push\n\t"
".set mips2\n\t"
"ll %1, %2\n\t"
"addiu %0, %1, -1\n\t"
"sc %0, %2\n\t"
".set pop\n\t"
"beqz %0, 0b\n\t"
"addiu %0, %1, -1":
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
"m"( *pw ):
"memory"
);
return rv;
}
inline int atomic_conditional_increment( int * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int rv, tmp;
__asm__ __volatile__
(
"0:\n\t"
".set push\n\t"
".set mips2\n\t"
"ll %0, %2\n\t"
"beqz %0, 1f\n\t"
"addiu %1, %0, 1\n\t"
"sc %1, %2\n\t"
".set pop\n\t"
"beqz %1, 0b\n\t"
"addiu %0, %0, 1\n\t"
"1:":
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
"m"( *pw ):
"memory"
);
return rv;
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED

View File

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

View File

@@ -0,0 +1,167 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
//
// Copyright (c) 2006 Piotr Wyderski
// Copyright (c) 2006 Tomas Puverle
// Copyright (c) 2006 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// Thanks to Michael van der Westhuizen
#include <boost/detail/sp_typeinfo.hpp>
#include <inttypes.h> // int32_t
namespace boost
{
namespace detail
{
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
{
__asm__ __volatile__( "cas [%1], %2, %0"
: "+r" (swap_)
: "r" (dest_), "r" (compare_)
: "memory" );
return swap_;
}
inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
{
// long r = *pw;
// *pw += dv;
// return r;
for( ;; )
{
int32_t r = *pw;
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
{
return r;
}
}
}
inline void atomic_increment( int32_t * pw )
{
atomic_fetch_and_add( pw, 1 );
}
inline int32_t atomic_decrement( int32_t * pw )
{
return atomic_fetch_and_add( pw, -1 );
}
inline int32_t atomic_conditional_increment( int32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
for( ;; )
{
int32_t r = *pw;
if( r == 0 )
{
return r;
}
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
{
return r;
}
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int32_t use_count_; // #shared
int32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return const_cast< int32_t const volatile & >( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED

View File

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

View File

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

View File

@@ -0,0 +1,136 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_pt.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/sp_typeinfo.hpp>
#include <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;
virtual void * get_untyped_deleter() = 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_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED

View File

@@ -0,0 +1,162 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
//
// Copyright (c) 2006 Piotr Wyderski
// Copyright (c) 2006 Tomas Puverle
// Copyright (c) 2006 Peter Dimov
// Copyright (c) 2011 Emil Dotchevski
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// Thanks to Michael van der Westhuizen
#include <boost/detail/sp_typeinfo.hpp>
#include <inttypes.h> // uint32_t
namespace boost
{
namespace detail
{
inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
{
return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
}
inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
{
// long r = *pw;
// *pw += dv;
// return r;
for( ;; )
{
uint32_t r = *pw;
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
{
return r;
}
}
}
inline void atomic_increment( uint32_t * pw )
{
(void) __builtin_cellAtomicIncr32( pw );
}
inline uint32_t atomic_decrement( uint32_t * pw )
{
return __builtin_cellAtomicDecr32( pw );
}
inline uint32_t atomic_conditional_increment( uint32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
for( ;; )
{
uint32_t r = *pw;
if( r == 0 )
{
return r;
}
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
{
return r;
}
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
uint32_t use_count_; // #shared
uint32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return const_cast< uint32_t const volatile & >( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED

View File

@@ -0,0 +1,114 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
//
// detail/sp_counted_base_solaris.hpp
// based on: detail/sp_counted_base_w32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
// Copyright 2006 Michael van der Westhuizen
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <atomic.h>
namespace boost
{
namespace detail
{
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
uint32_t use_count_; // #shared
uint32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_inc_32( &use_count_ );
}
bool add_ref_lock() // true on success
{
for( ;; )
{
uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
if( tmp == 0 ) return false;
if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
}
}
void release() // nothrow
{
if( atomic_dec_32_nv( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_inc_32( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_dec_32_nv( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED

View File

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

View File

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

View File

@@ -0,0 +1,151 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
//
// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
// based on: detail/sp_counted_base_w32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
// Copyright 2006 Michael van der Westhuizen
// Copyright 2012 IBM Corp.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
extern "builtin" void __lwsync(void);
extern "builtin" void __isync(void);
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
extern "builtin" int __compare_and_swap(volatile int*, int*, int);
namespace boost
{
namespace detail
{
inline void atomic_increment( int *pw )
{
// ++*pw;
__lwsync();
__fetch_and_add(pw, 1);
__isync();
}
inline int atomic_decrement( int *pw )
{
// return --*pw;
__lwsync();
int originalValue = __fetch_and_add(pw, -1);
__isync();
return (originalValue - 1);
}
inline int atomic_conditional_increment( int *pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
__lwsync();
int v = *const_cast<volatile int*>(pw);
for (;;)
// loop until state is known
{
if (v == 0) return 0;
if (__compare_and_swap(pw, &v, v + 1))
{
__isync(); return (v + 1);
}
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int use_count_; // #shared
int weak_count_; // #weak + (#shared != 0)
char pad[64] __attribute__((__aligned__(64)));
// pad to prevent false sharing
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return *const_cast<volatile int*>(&use_count_);
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED

View File

@@ -0,0 +1,131 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_w32.hpp
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
// Lock-free algorithm by Alexander Terekhov
//
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
// formulation
//
#include <boost/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;
virtual void * get_untyped_deleter() = 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_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED

View File

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

View File

@@ -0,0 +1,39 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_forward.hpp
//
// Copyright 2008,2012 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
namespace boost
{
namespace detail
{
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
{
return static_cast< T&& >( t );
}
#endif
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED

View File

@@ -0,0 +1,69 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/smart_ptr/detail/sp_has_sync.hpp
//
// Copyright (c) 2008, 2009 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics
// are available.
//
#ifndef BOOST_SP_NO_SYNC
#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
# define BOOST_SP_HAS_SYNC
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
# define BOOST_SP_HAS_SYNC
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
#define BOOST_SP_HAS_SYNC
#if defined( __arm__ ) || defined( __armel__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __hppa ) || defined( __hppa__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __m68k__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sh__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
#undef BOOST_SP_HAS_SYNC
#endif
#endif
#endif // #ifndef BOOST_SP_NO_SYNC
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED

View File

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

View File

@@ -0,0 +1,45 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_nullptr_t.hpp
//
// Copyright 2013 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <cstddef>
#if !defined( BOOST_NO_CXX11_NULLPTR )
namespace boost
{
namespace detail
{
#if defined( __clang__ ) && !defined( _LIBCPP_VERSION ) && !defined( BOOST_NO_CXX11_DECLTYPE )
typedef decltype(nullptr) sp_nullptr_t;
#else
typedef std::nullptr_t sp_nullptr_t;
#endif
} // namespace detail
} // namespace boost
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED

View File

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

View File

@@ -0,0 +1,120 @@
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
//
// Copyright (c) 2008, 2011 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/smart_ptr/detail/yield_k.hpp>
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
# define BOOST_SP_ARM_BARRIER "dmb"
# define BOOST_SP_ARM_HAS_LDREX
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
# define BOOST_SP_ARM_HAS_LDREX
#else
# define BOOST_SP_ARM_BARRIER ""
#endif
namespace boost
{
namespace detail
{
class spinlock
{
public:
int v_;
public:
bool try_lock()
{
int r;
#ifdef BOOST_SP_ARM_HAS_LDREX
__asm__ __volatile__(
"ldrex %0, [%2]; \n"
"cmp %0, %1; \n"
"strexne %0, %1, [%2]; \n"
BOOST_SP_ARM_BARRIER :
"=&r"( r ): // outputs
"r"( 1 ), "r"( &v_ ): // inputs
"memory", "cc" );
#else
__asm__ __volatile__(
"swp %0, %1, [%2];\n"
BOOST_SP_ARM_BARRIER :
"=&r"( r ): // outputs
"r"( 1 ), "r"( &v_ ): // inputs
"memory", "cc" );
#endif
return r == 0;
}
void lock()
{
for( unsigned k = 0; !try_lock(); ++k )
{
boost::detail::yield( k );
}
}
void unlock()
{
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
*const_cast< int volatile* >( &v_ ) = 0;
}
public:
class scoped_lock
{
private:
spinlock & sp_;
scoped_lock( scoped_lock const & );
scoped_lock & operator=( scoped_lock const & );
public:
explicit scoped_lock( spinlock & sp ): sp_( sp )
{
sp.lock();
}
~scoped_lock()
{
sp_.unlock();
}
};
};
} // namespace detail
} // namespace boost
#define BOOST_DETAIL_SPINLOCK_INIT {0}
#undef BOOST_SP_ARM_BARRIER
#undef BOOST_SP_ARM_HAS_LDREX
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,148 @@
#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// yield_k.hpp
//
// Copyright (c) 2008 Peter Dimov
//
// void yield( unsigned k );
//
// Typical use:
//
// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/config.hpp>
// BOOST_SMT_PAUSE
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
extern "C" void _mm_pause();
#define BOOST_SMT_PAUSE _mm_pause();
#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
#endif
//
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
#endif
namespace boost
{
namespace detail
{
#if !defined( BOOST_USE_WINDOWS_H )
extern "C" void __stdcall Sleep( unsigned long ms );
#endif
inline void yield( unsigned k )
{
if( k < 4 )
{
}
#if defined( BOOST_SMT_PAUSE )
else if( k < 16 )
{
BOOST_SMT_PAUSE
}
#endif
else if( k < 32 )
{
Sleep( 0 );
}
else
{
Sleep( 1 );
}
}
} // namespace detail
} // namespace boost
#elif defined( BOOST_HAS_PTHREADS )
#include <sched.h>
#include <time.h>
namespace boost
{
namespace detail
{
inline void yield( unsigned k )
{
if( k < 4 )
{
}
#if defined( BOOST_SMT_PAUSE )
else if( k < 16 )
{
BOOST_SMT_PAUSE
}
#endif
else if( k < 32 || k & 1 )
{
sched_yield();
}
else
{
// g++ -Wextra warns on {} or {0}
struct timespec rqtp = { 0, 0 };
// POSIX says that timespec has tv_sec and tv_nsec
// But it doesn't guarantee order or placement
rqtp.tv_sec = 0;
rqtp.tv_nsec = 1000;
nanosleep( &rqtp, 0 );
}
}
} // namespace detail
} // namespace boost
#else
namespace boost
{
namespace detail
{
inline void yield( unsigned )
{
}
} // namespace detail
} // namespace boost
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED

View File

@@ -0,0 +1,144 @@
#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
//
// enable_shared_from_raw.hpp
//
// Copyright 2002, 2009 Peter Dimov
// Copyright 2008-2009 Frank Mori Hess
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
namespace boost
{
template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
namespace detail
{
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
} // namespace detail
class enable_shared_from_raw
{
protected:
enable_shared_from_raw()
{
}
enable_shared_from_raw( enable_shared_from_raw const & )
{
}
enable_shared_from_raw & operator=( enable_shared_from_raw const & )
{
return *this;
}
~enable_shared_from_raw()
{
BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
}
private:
void init_weak_once() const
{
if( weak_this_.expired() )
{
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
weak_this_ = shared_this_;
}
}
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
private:
template<class Y> friend class shared_ptr;
template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
#endif
shared_ptr<void> shared_from_this()
{
init_weak_once();
return shared_ptr<void>( weak_this_ );
}
shared_ptr<const void> shared_from_this() const
{
init_weak_once();
return shared_ptr<const void>( weak_this_ );
}
// Note: invoked automatically by shared_ptr; do not call
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
{
BOOST_ASSERT( ppx != 0 );
if( weak_this_.expired() )
{
weak_this_ = *ppx;
}
else if( shared_this_.use_count() != 0 )
{
BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
BOOST_ASSERT( pd != 0 );
pd->set_deleter( *ppx );
ppx->reset( shared_this_, ppx->get() );
shared_this_.reset();
}
}
mutable weak_ptr<void> weak_this_;
private:
mutable shared_ptr<void> shared_this_;
};
template<typename T>
boost::shared_ptr<T> shared_from_raw(T *p)
{
BOOST_ASSERT(p != 0);
return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
}
template<typename T>
boost::weak_ptr<T> weak_from_raw(T *p)
{
BOOST_ASSERT(p != 0);
boost::weak_ptr<T> result;
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p);
return result;
}
namespace detail
{
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe )
{
if( pe != 0 )
{
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
}
}
} // namepsace detail
} // namespace boost
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED

View File

@@ -0,0 +1,79 @@
#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
//
// enable_shared_from_this.hpp
//
// Copyright 2002, 2009 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
//
#include <boost/smart_ptr/weak_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
namespace boost
{
template<class T> class enable_shared_from_this
{
protected:
enable_shared_from_this() BOOST_NOEXCEPT
{
}
enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT
{
}
enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT
{
return *this;
}
~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
{
}
public:
shared_ptr<T> shared_from_this()
{
shared_ptr<T> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
shared_ptr<T const> shared_from_this() const
{
shared_ptr<T const> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
public: // actually private, but avoids compiler template friendship issues
// Note: invoked automatically by shared_ptr; do not call
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
{
if( weak_this_.expired() )
{
weak_this_ = shared_ptr<T>( *ppx, py );
}
}
private:
mutable weak_ptr<T> weak_this_;
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED

View File

@@ -0,0 +1,324 @@
#ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
//
// intrusive_ptr.hpp
//
// Copyright (c) 2001, 2002 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
//
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/config/no_tr1/functional.hpp> // for std::less
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
#include <iosfwd> // for std::basic_ostream
#else
#include <ostream>
#endif
#endif
namespace boost
{
//
// intrusive_ptr
//
// A smart pointer that uses intrusive reference counting.
//
// Relies on unqualified calls to
//
// void intrusive_ptr_add_ref(T * p);
// void intrusive_ptr_release(T * p);
//
// (p != 0)
//
// The object is responsible for destroying itself.
//
template<class T> class intrusive_ptr
{
private:
typedef intrusive_ptr this_type;
public:
typedef T element_type;
intrusive_ptr() BOOST_NOEXCEPT : px( 0 )
{
}
intrusive_ptr( T * p, bool add_ref = true ): px( p )
{
if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
#else
intrusive_ptr( intrusive_ptr<U> const & rhs )
#endif
: px( rhs.get() )
{
if( px != 0 ) intrusive_ptr_add_ref( px );
}
#endif
intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
{
if( px != 0 ) intrusive_ptr_add_ref( px );
}
~intrusive_ptr()
{
if( px != 0 ) intrusive_ptr_release( px );
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
#endif
// Move support
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px )
{
rhs.px = 0;
}
intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT
{
this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
return *this;
}
#endif
intrusive_ptr & operator=(intrusive_ptr const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
intrusive_ptr & operator=(T * rhs)
{
this_type(rhs).swap(*this);
return *this;
}
void reset() BOOST_NOEXCEPT
{
this_type().swap( *this );
}
void reset( T * rhs )
{
this_type( rhs ).swap( *this );
}
T * get() const BOOST_NOEXCEPT
{
return px;
}
T & operator*() const
{
BOOST_ASSERT( px != 0 );
return *px;
}
T * operator->() const
{
BOOST_ASSERT( px != 0 );
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
{
T * tmp = px;
px = rhs.px;
rhs.px = tmp;
}
private:
T * px;
};
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
{
return a.get() != b.get();
}
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
{
return a.get() == b;
}
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
{
return a.get() != b;
}
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
{
return a == b.get();
}
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
{
return a != b.get();
}
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
// Resolve the ambiguity between our op!= and the one in rel_ops
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
{
return a.get() != b.get();
}
#endif
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
{
return std::less<T *>()(a.get(), b.get());
}
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
{
lhs.swap(rhs);
}
// mem_fn support
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
{
return p.get();
}
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
{
return static_cast<T *>(p.get());
}
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
{
return const_cast<T *>(p.get());
}
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
{
return dynamic_cast<T *>(p.get());
}
// operator<<
#if !defined(BOOST_NO_IOSTREAM)
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
{
os << p.get();
return os;
}
#else
// in STLport's no-iostreams mode no iostream symbols can be used
#ifndef _STLP_NO_IOSTREAMS
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
using std::basic_ostream;
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
# else
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
# endif
{
os << p.get();
return os;
}
#endif // _STLP_NO_IOSTREAMS
#endif // __GNUC__ < 3
#endif // !defined(BOOST_NO_IOSTREAM)
// hash_value
template< class T > struct hash;
template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
{
return boost::hash< T* >()( p.get() );
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,187 @@
/*
* Copyright Andrey Semashev 2007 - 2013.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file intrusive_ref_counter.hpp
* \author Andrey Semashev
* \date 12.03.2009
*
* This header contains a reference counter class for \c intrusive_ptr.
*/
#ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
#define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(_MSC_VER)
#pragma warning(push)
// This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter:
// 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
// Note that there is no inline specifier in the declarations.
#pragma warning(disable: 4396)
#endif
namespace boost {
namespace sp_adl_block {
/*!
* \brief Thread unsafe reference counter policy for \c intrusive_ref_counter
*
* The policy instructs the \c intrusive_ref_counter base class to implement
* a reference counter suitable for single threaded use only. Pointers to the same
* object with this kind of reference counter must not be used by different threads.
*/
struct thread_unsafe_counter
{
typedef unsigned int type;
static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT
{
return counter;
}
static void increment(unsigned int& counter) BOOST_NOEXCEPT
{
++counter;
}
static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT
{
return --counter;
}
};
/*!
* \brief Thread safe reference counter policy for \c intrusive_ref_counter
*
* The policy instructs the \c intrusive_ref_counter base class to implement
* a thread-safe reference counter, if the target platform supports multithreading.
*/
struct thread_safe_counter
{
typedef boost::detail::atomic_count type;
static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT
{
return static_cast< unsigned int >(static_cast< long >(counter));
}
static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
{
++counter;
}
static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
{
return --counter;
}
};
template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
class intrusive_ref_counter;
template< typename DerivedT, typename CounterPolicyT >
void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
template< typename DerivedT, typename CounterPolicyT >
void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
/*!
* \brief A reference counter base class
*
* This base class can be used with user-defined classes to add support
* for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT.
* Upon releasing the last \c intrusive_ptr referencing the object
* derived from the \c intrusive_ref_counter class, operator \c delete
* is automatically called on the pointer to the object.
*
* The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter.
*/
template< typename DerivedT, typename CounterPolicyT >
class intrusive_ref_counter
{
private:
//! Reference counter type
typedef typename CounterPolicyT::type counter_type;
//! Reference counter
mutable counter_type m_ref_counter;
public:
/*!
* Default constructor
*
* \post <tt>use_count() == 0</tt>
*/
intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
{
}
/*!
* Copy constructor
*
* \post <tt>use_count() == 0</tt>
*/
intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
{
}
/*!
* Assignment
*
* \post The reference counter is not modified after assignment
*/
intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }
/*!
* \return The reference counter
*/
unsigned int use_count() const BOOST_NOEXCEPT
{
return CounterPolicyT::load(m_ref_counter);
}
protected:
/*!
* Destructor
*/
BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
};
template< typename DerivedT, typename CounterPolicyT >
inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
{
CounterPolicyT::increment(p->m_ref_counter);
}
template< typename DerivedT, typename CounterPolicyT >
inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
{
if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
delete static_cast< const DerivedT* >(p);
}
} // namespace sp_adl_block
using sp_adl_block::intrusive_ref_counter;
using sp_adl_block::thread_unsafe_counter;
using sp_adl_block::thread_safe_counter;
} // namespace boost
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_

View File

@@ -0,0 +1,22 @@
#ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
#define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
// make_shared.hpp
//
// Copyright (c) 2007, 2008, 2012 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://www.boost.org/libs/smart_ptr/make_shared.html
// for documentation.
#include <boost/smart_ptr/make_shared_object.hpp>
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE )
# include <boost/smart_ptr/make_shared_array.hpp>
# include <boost/smart_ptr/allocate_shared_array.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -0,0 +1,157 @@
#ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
//
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/detail/workaround.hpp>
#ifndef BOOST_NO_AUTO_PTR
# include <memory> // for std::auto_ptr
#endif
namespace boost
{
// Debug hooks
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
void sp_scalar_constructor_hook(void * p);
void sp_scalar_destructor_hook(void * p);
#endif
// scoped_ptr mimics a built-in pointer except that it guarantees deletion
// of the object pointed to, either on destruction of the scoped_ptr or via
// an explicit reset(). scoped_ptr is a simple solution for simple needs;
// use shared_ptr or std::auto_ptr if your needs are more complex.
template<class T> class scoped_ptr // noncopyable
{
private:
T * px;
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
typedef scoped_ptr<T> this_type;
void operator==( scoped_ptr const& ) const;
void operator!=( scoped_ptr const& ) const;
public:
typedef T element_type;
explicit scoped_ptr( T * p = 0 ): px( p ) // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px );
#endif
}
#ifndef BOOST_NO_AUTO_PTR
explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px );
#endif
}
#endif
~scoped_ptr() // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px );
#endif
boost::checked_delete( px );
}
void reset(T * p = 0) // never throws
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
T & operator*() const // never throws
{
BOOST_ASSERT( px != 0 );
return *px;
}
T * operator->() const // never throws
{
BOOST_ASSERT( px != 0 );
return px;
}
T * get() const BOOST_NOEXCEPT
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
void swap(scoped_ptr & b) BOOST_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
px = tmp;
}
};
#if !defined( BOOST_NO_CXX11_NULLPTR )
template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
{
a.swap(b);
}
// get_pointer(p) is a generic way to say p.get()
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
{
return p.get();
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED

View File

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

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