Compare commits

...

54 Commits

Author SHA1 Message Date
d38f64ded9 Update documentation 2020-06-06 00:35:12 +03:00
b66fe51566 Avoid g++ 4.4 conflict between hash() and boost::hash 2020-06-06 00:15:58 +03:00
1b5568d585 Add sp_unordered_test 2020-06-05 18:54:44 +03:00
fad0c20263 Add owner_hash 2020-06-05 18:45:00 +03:00
1c61e54b13 Update documentation 2020-06-05 18:12:59 +03:00
a0fc1e6daa Add wp_unordered_test 2020-06-04 20:52:17 +03:00
5dd84ea389 Add .owner_hash_value to shared/weak_ptr, hash_value, std::hash/equal_to specializations for weak_ptr 2020-06-04 20:40:57 +03:00
bc677e9098 Do not require boost::hash in the std::hash specializations 2020-06-03 17:38:03 +03:00
688cfed63e Add Boost::bind to CMake test dependencies 2020-06-03 07:38:07 +03:00
c63dc266b9 Update submodule libs/bind on Travis/Appveyor 2020-06-02 21:51:00 +03:00
6c181a0707 When BOOST_SP_REPORT_IMPLEMENTATION is defined, report what platform-specific atomic implementation is used 2020-06-02 20:51:38 +03:00
4047290b85 Add multithreaded tests 2020-06-02 18:58:45 +03:00
dc6c76d7e9 Move lightweight_thread.hpp to smart_ptr/detail 2020-06-02 17:55:15 +03:00
5a18ffdc56 Add std::hash specializations for shared_ptr, local_shared_ptr, intrusive_ptr 2020-06-02 05:59:23 +03:00
09fdd5ebfd Add FreeBSD to Travis 2020-06-01 18:18:57 +03:00
911874e139 Add gcc-10 to Travis 2020-06-01 18:18:12 +03:00
c7c0eacb74 Add initializers to eq and lt 2020-06-01 15:08:53 +03:00
9ed9f43ca8 Document owner_less, owner_equal_to 2020-06-01 03:53:21 +03:00
0ddf990869 Add noexcept to owner_less, owner_equal_to 2020-06-01 03:44:41 +03:00
a08a5f3d41 Update introduction 2020-06-01 03:26:02 +03:00
77c2d4cad7 Add owner_less_test2 2020-06-01 03:13:42 +03:00
fd612dc114 Add owner_equal_to 2020-06-01 03:05:34 +03:00
e67ebef9a7 Update changelog 2020-06-01 02:01:10 +03:00
6f5b9c7b37 Document local_shared_ptr::owner_equals 2020-06-01 01:59:40 +03:00
91f3aa0386 Add local_shared_ptr::owner_equals 2020-06-01 01:35:25 +03:00
686a354f21 Add lsp_owner_before_test 2020-06-01 01:16:46 +03:00
efceb04665 Asciidoctor 2 fixes 2020-06-01 01:02:09 +03:00
ca57860ae2 Update footer 2020-06-01 00:41:25 +03:00
9dcd05f918 Document owner_equals 2020-06-01 00:40:02 +03:00
4b724ab3f8 Add mixed shared_count/weak_count operator== overloads to avoid refcount manipulation 2020-05-31 22:07:36 +03:00
58915ca2fe Add owner_equals 2020-05-31 21:41:06 +03:00
62b0e5cdf4 Add mixed shared_count/weak_count operator< overloads to avoid refcount manipulation 2020-05-31 21:12:12 +03:00
951ff783b5 Add sp_owner_before_test 2020-05-31 20:33:24 +03:00
6421394e70 Fix msvc-8.0 failures 2020-05-31 20:14:25 +03:00
121312cc22 Use allocator access utilities 2020-05-21 23:14:23 -04:00
1e5df9d551 Merge pull request #79 from EugeneZelenko/use-boost-override
Fix Clang-tidy modernize-use-override warnings.
2020-05-19 01:58:20 +03:00
496127ab99 Merge pull request #77 from eldiener/develop
Changes for Embarcadero C++ clang-based compilers, targeting Boost 1.74
2020-05-19 01:57:37 +03:00
2af343a2cb Fix Clang-tidy modernize-use-override warnings. 2020-05-12 18:01:55 -07:00
c6b3700ef1 Merge branch 'develop' of https://github.com/boostorg/smart_ptr into cppbuilder 2020-05-06 11:32:12 -04:00
2a93d30e73 Change conditions to be the same. 2020-05-06 11:31:57 -04:00
02cc561248 Only use warnings-as-errors on msvc, gcc, clang 2020-04-28 05:05:57 +03:00
066b398114 Disable -Wc11-extensions in sp_counted_base_clang.hpp 2020-04-27 00:50:15 +03:00
9c43c69c14 Add sp_pedantic_test 2020-04-26 19:57:05 +03:00
eb8998cd91 Add Clang 10 to Travis 2020-04-26 18:27:35 +03:00
df06c324a7 Merge branch 'develop' of https://github.com/boostorg/smart_ptr into cppbuilder 2020-04-19 02:49:06 -04:00
0ddfab493c Do not enable -Wsuggest-override in C++03 mode 2020-04-14 07:12:35 +03:00
a2732e207a Add BOOST_OVERRIDE to sp_counted_impl.hpp 2020-04-14 00:55:52 +03:00
5be7523ebe Merge branch 'develop' into feature/suggest-override 2020-04-14 00:45:24 +03:00
2320dafc03 Add BOOST_OVERRIDE to bad_weak_ptr.hpp and local_counted_base.hpp 2020-04-14 00:42:57 +03:00
7ab4093f46 Use shared_ptr and make_shared in sp_override_test 2020-04-14 00:32:25 +03:00
296c203135 Rename sp_warning_test to sp_override_test 2020-04-14 00:15:32 +03:00
2dd35e5fbc Mark functions with BOOST_OVERRIDE 2020-04-13 15:34:13 -04:00
977544feda Add sp_warning_test 2020-04-08 21:25:36 +03:00
cd562eb053 Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. 2020-03-26 17:17:22 -04:00
95 changed files with 2899 additions and 364 deletions

View File

@ -37,6 +37,10 @@ matrix:
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14
- os: freebsd
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17,2a
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
@ -156,6 +160,28 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14
addons:
apt:
packages:
- g++-10
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=17,2a
addons:
apt:
packages:
- g++-10
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
@ -299,6 +325,19 @@ matrix:
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: xenial
compiler: clang++-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
compiler: clang++-8
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
@ -386,6 +425,7 @@ install:
- git submodule init tools/boost_install
- git submodule init tools/cmake
- git submodule init libs/preprocessor
- git submodule init libs/bind
- git submodule update # no --jobs 3 on non-amd64
- cp -r $TRAVIS_BUILD_DIR/* libs/smart_ptr
- ./bootstrap.sh

View File

@ -70,6 +70,7 @@ install:
- git submodule init tools/build
- git submodule init libs/headers
- git submodule init tools/boost_install
- git submodule init libs/bind
- git submodule update --jobs 3
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\smart_ptr\
- cmd /c bootstrap

View File

@ -1,6 +1,7 @@
<style>
*:not(pre)>code { background: none; color: #600000; }
:not(pre):not([class^=L])>code { background: none; color: #600000; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }
</style>

View File

@ -18,40 +18,26 @@ Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes
:leveloffset: +1
include::smart_ptr/introduction.adoc[]
include::smart_ptr/changelog.adoc[]
include::smart_ptr/scoped_ptr.adoc[]
include::smart_ptr/scoped_array.adoc[]
include::smart_ptr/shared_ptr.adoc[]
include::smart_ptr/weak_ptr.adoc[]
include::smart_ptr/make_shared.adoc[]
include::smart_ptr/enable_shared_from_this.adoc[]
include::smart_ptr/enable_shared_from.adoc[]
include::smart_ptr/make_unique.adoc[]
include::smart_ptr/allocate_unique.adoc[]
include::smart_ptr/intrusive_ptr.adoc[]
include::smart_ptr/intrusive_ref_counter.adoc[]
include::smart_ptr/local_shared_ptr.adoc[]
include::smart_ptr/make_local_shared.adoc[]
include::smart_ptr/pointer_cast.adoc[]
include::smart_ptr/pointer_to_other.adoc[]
include::smart_ptr/atomic_shared_ptr.adoc[]
include::smart_ptr/owner_less.adoc[]
include::smart_ptr/owner_equal_to.adoc[]
include::smart_ptr/owner_hash.adoc[]
// appendix
include::smart_ptr/techniques.adoc[]
@ -73,7 +59,7 @@ This documentation is
* Copyright 1999 Greg Colvin
* Copyright 1999 Beman Dawes
* Copyright 2002 Darin Adler
* Copyright 2003-2017 Peter Dimov
* Copyright 2003-2020 Peter Dimov
* Copyright 2005, 2006 Ion Gaztañaga
* Copyright 2008 Frank Mori Hess
* Copyright 2012-2017 Glen Fernandes

View File

@ -1,5 +1,5 @@
////
Copyright 2019 Peter Dimov
Copyright 2019, 2020 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
@ -13,6 +13,15 @@ http://www.boost.org/LICENSE_1_0.txt
:toc-title:
:idprefix: changelog_
## Changes in 1.74.0
* Added `owner_equals` to `shared_ptr`, `weak_ptr`, `local_shared_ptr`
* Added `owner_hash_value` to `shared_ptr`, `weak_ptr`
* Added `owner_equal_to`, `owner_hash`
* Added `std::hash` specializations for `shared_ptr`, `local_shared_ptr`
* Added `boost::hash` support to, and `std::hash`, `std::equal_to`
specializations for, `weak_ptr`
## Changes in 1.72.0
* Added `allocate_unique`

View File

@ -31,7 +31,7 @@ This library provides six smart pointer class templates:
* `<<scoped_ptr,scoped_ptr>>`, used to contain ownership of a dynamically allocated object to the current scope;
* `<<scoped_array,scoped_array>>`, which provides scoped ownership for a dynamically allocated array;
* `<<shared_ptr,shared_ptr>>`, a versatile tool for managing shared ownership of an object or array;
* `<<weak_ptr,weak_ptr>>`, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr;
* `<<weak_ptr,weak_ptr>>`, a non-owning observer to a `shared_ptr`-managed object that can be promoted temporarily to `shared_ptr`;
* `<<intrusive_ptr,intrusive_ptr>>`, a pointer to objects with an embedded reference count;
* `<<local_shared_ptr,local_shared_ptr>>`, providing shared ownership within a single thread.
@ -39,10 +39,11 @@ This library provides six smart pointer class templates:
In addition, the library contains the following supporting utility functions and classes:
* `<<make_shared,make_shared>>`, a factory function for creating objects that returns a `shared_ptr`;
* `<<make_shared,make_shared>>` and `allocate_shared`, factory functions for creating objects that return a `shared_ptr`;
* `<<make_unique,make_unique>>`, a factory function returning `std::unique_ptr`;
* `<<allocate_unique,allocate_unique>>`, a factory function for creating objects using an allocator that returns a `std::unique_ptr`;
* `<<enable_shared_from_this,enable_shared_from_this>>`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`;
* `<<enable_shared_from,enable_shared_from>>`, a newer and better replacement for `enable_shared_from_this`;
* `<<pointer_to_other,pointer_to_other>>`, a helper trait for converting one smart pointer type to another;
* `<<pointer_cast,static_pointer_cast>>` and companions, generic smart pointer casts;
* `<<intrusive_ref_counter,intrusive_ref_counter>>`, a helper base class containing a reference count.

View File

@ -174,7 +174,8 @@ template<class Y> intrusive_ptr(intrusive_ptr<Y> && r);
[none]
* {blank}
+
Postconditions:: `get()` equals the old value of `r.get()`. `r.get() == 0`.
Postconditions::
`get()` equals the old value of `r.get()`. `r.get() == 0`.
### destructor
@ -185,7 +186,8 @@ Postconditions:: `get()` equals the old value of `r.get()`. `r.get() == 0`.
[none]
* {blank}
+
Effects:: `if(get() != 0) intrusive_ptr_release(get());`.
Effects::
`if(get() != 0) intrusive_ptr_release(get());`.
### assignment
@ -245,7 +247,8 @@ void reset(T * r, bool add_ref);
[none]
* {blank}
+
Effects:: Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`.
Effects::
Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`.
### indirection
@ -278,7 +281,8 @@ T * get() const noexcept;
[none]
* {blank}
+
Returns:: the stored pointer.
Returns::
the stored pointer.
### detach
@ -325,7 +329,8 @@ void swap(intrusive_ptr & b) noexcept;
[none]
* {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
Effects::
Exchanges the contents of the two smart pointers.
## Free Functions
@ -412,7 +417,8 @@ template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept
[none]
* {blank}
+
Effects:: Equivalent to `a.swap(b)`.
Effects::
Equivalent to `a.swap(b)`.
### get_pointer
@ -437,7 +443,8 @@ template<class T, class U>
[none]
* {blank}
+
Returns:: `intrusive_ptr<T>(static_cast<T*>(r.get()))`.
Returns::
`intrusive_ptr<T>(static_cast<T*>(r.get()))`.
### const_pointer_cast
@ -449,7 +456,8 @@ template<class T, class U>
[none]
* {blank}
+
Returns:: `intrusive_ptr<T>(const_cast<T*>(r.get()))`.
Returns::
`intrusive_ptr<T>(const_cast<T*>(r.get()))`.
### dynamic_pointer_cast
@ -461,7 +469,8 @@ template<class T, class U>
[none]
* {blank}
+
Returns:: `intrusive_ptr<T>(dynamic_cast<T*>(r.get()))`.
Returns::
`intrusive_ptr<T>(dynamic_cast<T*>(r.get()))`.
### operator<<

View File

@ -111,7 +111,8 @@ intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
[none]
* {blank}
+
Effects:: Does nothing, reference counter is not modified.
Effects::
Does nothing, reference counter is not modified.
### use_count
@ -137,7 +138,8 @@ template<class Derived, class CounterPolicy>
[none]
* {blank}
+
Effects:: Increments the reference counter.
Effects::
Increments the reference counter.
### intrusive_ptr_release

View File

@ -124,7 +124,7 @@ namespace boost {
template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept;
// accessors
T & operator*() const noexcept; // only valid when T is not an array type
T * operator->() const noexcept; // only valid when T is not an array type
@ -143,12 +143,16 @@ namespace boost {
template<class Y> operator weak_ptr<Y>() const noexcept;
// swap
void swap(local_shared_ptr & b) noexcept;
// owner_before
template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(local_shared_ptr<Y> const & r) const noexcept;
// owner_equals
template<class Y> bool owner_equals(local_shared_ptr<Y> const & r) const noexcept;
};
// comparisons
@ -459,7 +463,8 @@ template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcep
[none]
* {blank}
+
Effects:: Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`.
Effects::
Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`.
### indirection
```
@ -497,7 +502,8 @@ element_type * get() const noexcept;
[none]
* {blank}
+
Returns:: The stored pointer.
Returns::
The stored pointer.
### local_use_count
```
@ -506,7 +512,8 @@ long local_use_count() const noexcept;
[none]
* {blank}
+
Returns:: The number of `local_shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.
Returns::
The number of `local_shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.
### conversions
```
@ -538,16 +545,28 @@ void swap(local_shared_ptr & b) noexcept;
[none]
* {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
Effects::
Exchanges the contents of the two smart pointers.
### owner_before
```
template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(local_shared_ptr<Y> const & r) const noexcept;
```
[none]
* {blank}
+
Effects:: See the description of `operator<`.
Returns::
See the description of `operator<`.
### owner_equals
```
template<class Y> bool owner_equals(local_shared_ptr<Y> const & r) const noexcept;
```
[none]
* {blank}
+
Returns::
`true` if and only if `*this` and `r` share ownership or are both empty.
## Free Functions
@ -631,7 +650,8 @@ template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) no
[none]
* {blank}
+
Effects:: Equivalent to `a.swap(b)`.
Effects::
Equivalent to `a.swap(b)`.
### get_pointer
```

View File

@ -0,0 +1,45 @@
////
Copyright 2020 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////
[#owner_equal_to]
# owner_equal_to
:toc:
:toc-title:
:idprefix: owner_equal_to_
## Description
`owner_equal_to<T>` is a helper function object that compares two smart
pointer objects using `owner_equals`.
## Synopsis
`owner_equal_to` is defined in `<boost/smart_ptr/owner_equal_to.hpp>`.
```
namespace boost {
template<class T = void> struct owner_equal_to
{
typedef bool result_type;
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept;
};
}
```
## Members
```
template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept;
```
[none]
* {blank}
+
Returns::
`u.owner_equals( v )`.

View File

@ -0,0 +1,56 @@
////
Copyright 2020 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////
[#owner_hash]
# owner_hash
:toc:
:toc-title:
:idprefix: owner_hash_to_
## Description
`owner_hash<T>` is a helper function object that takes a smart pointer `p`
and returns `p.owner_hash_value()`. It's useful for creating unordered
containers of `shared_ptr` that use ownership-based equality, instead of
the default pointer value equality. (It can be used with `weak_ptr` too,
but there's no need, because `boost::hash` and `std::hash` for `weak_ptr`
already use ownership-based equality.)
## Example
```
std::unordered_set< boost::shared_ptr<void>,
boost::owner_hash< boost::shared_ptr<void> >,
boost::owner_equal_to< boost::shared_ptr<void> > > set;
```
## Synopsis
`owner_hash` is defined in `<boost/smart_ptr/owner_hash.hpp>`.
```
namespace boost {
template<class T> struct owner_hash
{
typedef std::size_t result_type;
typedef T argument_type;
std::size_t operator()( T const & p ) const noexcept;
};
}
```
## Members
```
std::size_t operator()( T const & p ) const noexcept;
```
[none]
* {blank}
+
Returns::
`p.owner_hash_value()`.

View File

@ -0,0 +1,50 @@
////
Copyright 2020 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////
[#owner_less]
# owner_less
:toc:
:toc-title:
:idprefix: owner_less_
## Description
`owner_less<T>` is a helper function object that compares two smart
pointer objects using `owner_before`. It is only provided for compatibility
with {cpp}11 and corresponds to the standard component of the same name.
When using Boost smart pointers, the use of `owner_less` is unnecessary, as
the supplied `operator<` overloads (and, correspondingly, `std::less`) return
the same result.
## Synopsis
`owner_less` is defined in `<boost/smart_ptr/owner_less.hpp>`.
```
namespace boost {
template<class T = void> struct owner_less
{
typedef bool result_type;
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept;
};
}
```
## Members
```
template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept;
```
[none]
* {blank}
+
Returns::
`u.owner_before( v )`.

View File

@ -178,8 +178,13 @@ namespace boost {
void swap(shared_ptr & b) noexcept;
template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(shared_ptr<Y> const & r) const noexcept;
template<class Y> bool owner_before(weak_ptr<Y> const & r) const noexcept;
template<class Y> bool owner_equals(shared_ptr<Y> const & r) const noexcept;
template<class Y> bool owner_equals(weak_ptr<Y> const & r) const noexcept;
std::size_t owner_hash_value() const noexcept;
};
template<class T, class U>
@ -560,7 +565,8 @@ template<class Y> void reset(shared_ptr<Y> && r, element_type * p) noexcept;
[none]
* {blank}
+
Effects:: Equivalent to `shared_ptr(std::move(r), p).swap(*this)`.
Effects::
Equivalent to `shared_ptr(std::move(r), p).swap(*this)`.
### indirection
```
@ -598,7 +604,8 @@ element_type * get() const noexcept;
[none]
* {blank}
+
Returns:: The stored pointer.
Returns::
The stored pointer.
### unique
```
@ -607,7 +614,8 @@ bool unique() const noexcept;
[none]
* {blank}
+
Returns:: `use_count() == 1`.
Returns::
`use_count() == 1`.
### use_count
```
@ -616,7 +624,8 @@ long use_count() const noexcept;
[none]
* {blank}
+
Returns:: The number of `shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.
Returns::
The number of `shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.
### conversions
```
@ -641,19 +650,45 @@ void swap(shared_ptr & b) noexcept;
[none]
* {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
Effects::
Exchanges the contents of the two smart pointers.
### owner_before
```
template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(shared_ptr<Y> const & r) const noexcept;
```
```
template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(weak_ptr<Y> const & r) const noexcept;
```
[none]
* {blank}
+
Effects:: See the description of `operator<`.
Returns::
See the description of `operator<`.
### owner_equals
```
template<class Y> bool owner_equals(shared_ptr<Y> const & r) const noexcept;
```
```
template<class Y> bool owner_equals(weak_ptr<Y> const & r) const noexcept;
```
[none]
* {blank}
+
Returns::
`true` if and only if `*this` and `r` share ownership or are both empty.
### owner_hash_value
```
std::size_t owner_hash_value() const noexcept;
```
[none]
* {blank}
+
Returns::
An unspecified hash value such that two instances that share ownership
have the same hash value.
## Free Functions
@ -721,7 +756,8 @@ template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b) noexcept;
[none]
* {blank}
+
Effects:: Equivalent to `a.swap(b)`.
Effects::
Equivalent to `a.swap(b)`.
### get_pointer
```
@ -805,7 +841,8 @@ template<class D, class T>
[none]
* {blank}
+
Returns:: If `*this` owns a deleter `d` of type (cv-unqualified) `D`, returns `&d`; otherwise returns 0.
Returns::
If `*this` owns a deleter `d` of type (cv-unqualified) `D`, returns `&d`; otherwise returns 0.
### Atomic Access

View File

@ -112,6 +112,11 @@ namespace boost {
template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept;
template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept;
template<class Y> bool owner_equals( weak_ptr<Y> const & r ) const noexcept;
template<class Y> bool owner_equals( shared_ptr<Y> const & r ) const noexcept;
std::size_t owner_hash_value() const noexcept;
};
template<class T, class U>
@ -185,7 +190,8 @@ NOTE: These constructors are an extension, not present in `std::weak_ptr`.
[none]
* {blank}
+
Effects:: Destroys this `weak_ptr` but has no effect on the object its stored pointer points to.
Effects::
Destroys this `weak_ptr` but has no effect on the object its stored pointer points to.
### assignment
```
@ -214,7 +220,8 @@ long use_count() const noexcept;
[none]
* {blank}
+
Returns:: 0 if `*this` is empty; otherwise, the number of `shared_ptr` objects that share ownership with `*this`.
Returns::
0 if `*this` is empty; otherwise, the number of `shared_ptr` objects that share ownership with `*this`.
### expired
```
@ -223,7 +230,8 @@ bool expired() const noexcept;
[none]
* {blank}
+
Returns:: `use_count() == 0`.
Returns::
`use_count() == 0`.
### empty
```
@ -243,7 +251,8 @@ shared_ptr<T> lock() const noexcept;
[none]
* {blank}
+
Returns:: `expired()? shared_ptr<T>(): shared_ptr<T>(*this)`.
Returns::
`expired()? shared_ptr<T>(): shared_ptr<T>(*this)`.
### reset
```
@ -252,7 +261,8 @@ void reset() noexcept;
[none]
* {blank}
+
Effects:: Equivalent to `weak_ptr().swap(*this)`.
Effects::
Equivalent to `weak_ptr().swap(*this)`.
### swap
```
@ -261,8 +271,10 @@ void swap(weak_ptr & b) noexcept;
[none]
* {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
Effects::
Exchanges the contents of the two smart pointers.
### owner_before
```
template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept;
```
@ -272,7 +284,32 @@ template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept;
[none]
* {blank}
+
Returns:: See the description of `operator<`.
Returns::
See the description of `operator<`.
### owner_equals
```
template<class Y> bool owner_equals( weak_ptr<Y> const & r ) const noexcept;
```
```
template<class Y> bool owner_equals( shared_ptr<Y> const & r ) const noexcept;
```
[none]
* {blank}
+
Returns::
`true` if and only if `*this` and `r` share ownership or are both empty.
### owner_hash_value
```
std::size_t owner_hash_value() const noexcept;
```
[none]
* {blank}
+
Returns::
An unspecified hash value such that two instances that share ownership
have the same hash value.
## Free Functions
@ -298,7 +335,8 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept;
[none]
* {blank}
+
Effects:: Equivalent to `a.swap(b)`.
Effects::
Equivalent to `a.swap(b)`.
## Frequently Asked Questions

View File

@ -73,7 +73,7 @@ void * operator new(size_t n) throw(bad_alloc)
return p;
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
#if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
void * operator new(size_t n, nothrow_t const &) throw()
{
@ -95,7 +95,7 @@ void * operator new[](size_t n) throw(bad_alloc)
return p;
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
#if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
void * operator new[](size_t n, nothrow_t const &) throw()
{
@ -205,7 +205,7 @@ void operator delete(void * p) throw()
free(pm);
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
#if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
void operator delete(void * p, nothrow_t const &) throw()
{
@ -231,7 +231,7 @@ void operator delete[](void * p) throw()
free(pm);
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
#if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
void operator delete[](void * p, nothrow_t const &) throw()
{

View File

@ -21,168 +21,6 @@
// template<class F> int lw_thread_create( lw_thread_t & th, F f );
// void lw_thread_join( lw_thread_t th );
#include <boost/config.hpp>
#include <memory>
#include <cerrno>
#if defined( BOOST_HAS_PTHREADS )
#include <pthread.h>
namespace boost
{
namespace detail
{
typedef ::pthread_t lw_thread_t;
inline int lw_thread_create_( lw_thread_t* thread, const pthread_attr_t* attr, void* (*start_routine)( void* ), void* arg )
{
return ::pthread_create( thread, attr, start_routine, arg );
}
inline void lw_thread_join( lw_thread_t th )
{
::pthread_join( th, 0 );
}
} // namespace detail
} // namespace boost
#else // defined( BOOST_HAS_PTHREADS )
#include <windows.h>
#include <process.h>
namespace boost
{
namespace detail
{
typedef HANDLE lw_thread_t;
inline int lw_thread_create_( lw_thread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
{
HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
if( h != 0 )
{
*thread = h;
return 0;
}
else
{
return EAGAIN;
}
}
inline void lw_thread_join( lw_thread_t thread )
{
::WaitForSingleObject( thread, INFINITE );
::CloseHandle( thread );
}
} // namespace detail
} // namespace boost
#endif // defined( BOOST_HAS_PTHREADS )
namespace boost
{
namespace detail
{
class lw_abstract_thread
{
public:
virtual ~lw_abstract_thread() {}
virtual void run() = 0;
};
#if defined( BOOST_HAS_PTHREADS )
extern "C" void * lw_thread_routine( void * pv )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#else
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#endif
pt->run();
return 0;
}
#else
unsigned __stdcall lw_thread_routine( void * pv )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#else
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#endif
pt->run();
return 0;
}
#endif
template<class F> class lw_thread_impl: public lw_abstract_thread
{
public:
explicit lw_thread_impl( F f ): f_( f )
{
}
void run()
{
f_();
}
private:
F f_;
};
template<class F> int lw_thread_create( lw_thread_t & th, F f )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
#else
std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
#endif
int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() );
if( r == 0 )
{
p.release();
}
return r;
}
} // namespace detail
} // namespace boost
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED

View File

@ -21,11 +21,12 @@ public:
count_ = shared_count(base);
}
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
shared_count().swap(count_);
}
virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT {
shared_count local_cb_get_shared_count() const
BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return count_;
}
@ -73,7 +74,7 @@ inline typename enable_if_<is_unbounded_array<T>::value,
allocate_local_shared(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
@ -96,7 +97,7 @@ allocate_local_shared(const A& allocator)
count = extent<T>::value
};
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_size_array_state<other, count> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
@ -117,7 +118,7 @@ allocate_local_shared(const A& allocator, std::size_t count,
const typename remove_extent<T>::type& value)
{
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
@ -141,7 +142,7 @@ allocate_local_shared(const A& allocator,
count = extent<T>::value
};
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_size_array_state<other, count> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);

View File

@ -8,6 +8,7 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#include <boost/core/allocator_access.hpp>
#include <boost/core/alloc_construct.hpp>
#include <boost/core/first_scalar.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
@ -57,18 +58,6 @@ struct sp_align_up {
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
struct sp_bind_allocator {
typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
};
#else
template<class A, class T>
struct sp_bind_allocator {
typedef typename A::template rebind<T>::other type;
};
#endif
template<class T>
BOOST_CONSTEXPR inline std::size_t
sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
@ -171,7 +160,7 @@ public:
}
private:
typename sp_bind_allocator<A, type>::type other_;
typename boost::allocator_rebind<A, type>::type other_;
std::size_t size_;
};
@ -206,28 +195,29 @@ public:
return state_;
}
virtual void dispose() BOOST_SP_NOEXCEPT {
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
boost::alloc_destroy_n(state_.allocator(),
boost::first_scalar(sp_array_start<type>(this)),
state_.size() * sp_array_count<type>::value);
}
virtual void destroy() BOOST_SP_NOEXCEPT {
void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
sp_array_creator<allocator, sp_array_base> other(state_.allocator(),
state_.size());
this->~sp_array_base();
other.destroy(this);
}
virtual void* get_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT {
void* get_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
virtual void* get_local_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT {
void* get_local_deleter(const sp_typeinfo_&)
BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
virtual void* get_untyped_deleter() BOOST_SP_NOEXCEPT {
void* get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
@ -272,7 +262,7 @@ inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
@ -292,7 +282,7 @@ allocate_shared(const A& allocator)
count = extent<T>::value
};
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_size_array_state<other, extent<T>::value> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
@ -310,7 +300,7 @@ allocate_shared(const A& allocator, std::size_t count,
const typename remove_extent<T>::type& value)
{
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);
@ -331,7 +321,7 @@ allocate_shared(const A& allocator,
count = extent<T>::value
};
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_size_array_state<other, extent<T>::value> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, count);

View File

@ -10,6 +10,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/alloc_construct.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/core/first_scalar.hpp>
@ -61,30 +62,6 @@ struct sp_alloc_value {
boost::remove_extent<T>::type>::type type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
struct sp_alloc_to {
typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
};
#else
template<class A, class T>
struct sp_alloc_to {
typedef typename A::template rebind<T>::other type;
};
#endif
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct sp_alloc_type {
typedef typename std::allocator_traits<A>::pointer type;
};
#else
template<class A>
struct sp_alloc_type {
typedef typename A::pointer type;
};
#endif
template<class T, class P>
class sp_alloc_ptr {
public:
@ -296,7 +273,7 @@ operator!=(detail::sp_nullptr_t,
template<class A>
inline void
sp_alloc_clear(A& a, typename sp_alloc_type<A>::type p, std::size_t,
sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p, std::size_t,
boost::false_type)
{
boost::alloc_destroy(a, boost::to_address(p));
@ -304,8 +281,8 @@ sp_alloc_clear(A& a, typename sp_alloc_type<A>::type p, std::size_t,
template<class A>
inline void
sp_alloc_clear(A& a, typename sp_alloc_type<A>::type p, std::size_t n,
boost::true_type)
sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p,
std::size_t n, boost::true_type)
{
#if defined(BOOST_MSVC) && BOOST_MSVC < 1800
if (!p) {
@ -320,15 +297,15 @@ sp_alloc_clear(A& a, typename sp_alloc_type<A>::type p, std::size_t n,
template<class T, class A>
class alloc_deleter
: empty_value<typename detail::sp_alloc_to<A,
: empty_value<typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type> {
typedef typename detail::sp_alloc_to<A,
typedef typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type allocator;
typedef empty_value<allocator> base;
public:
typedef detail::sp_alloc_ptr<T,
typename detail::sp_alloc_type<allocator>::type> pointer;
typename allocator_pointer<allocator>::type> pointer;
explicit alloc_deleter(const allocator& a) BOOST_SP_NOEXCEPT
: base(empty_init_t(), a) { }
@ -349,7 +326,7 @@ namespace detail {
template<class T, class A>
class sp_alloc_make {
public:
typedef typename sp_alloc_to<A,
typedef typename boost::allocator_rebind<A,
typename sp_alloc_value<T>::type>::type allocator;
private:
@ -384,7 +361,7 @@ public:
}
private:
typedef typename sp_alloc_type<allocator>::type pointer;
typedef typename boost::allocator_pointer<allocator>::type pointer;
allocator a_;
std::size_t n_;

View File

@ -20,7 +20,7 @@
#include <boost/config.hpp>
#include <exception>
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
#endif
@ -33,7 +33,7 @@ namespace boost
// is compiled with -ps, the compiler issues an error.
// Hence, the temporary #pragma option -pc below.
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
#if defined(BOOST_BORLANDC) && BOOST_BORLANDC <= 0x564
# pragma option push -pc
#endif
@ -47,7 +47,7 @@ class bad_weak_ptr: public std::exception
{
public:
virtual char const * what() const BOOST_NOEXCEPT_OR_NOTHROW
char const * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
{
return "tr1::bad_weak_ptr";
}
@ -57,13 +57,13 @@ public:
# pragma clang diagnostic pop
#endif
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
#if defined(BOOST_BORLANDC) && BOOST_BORLANDC <= 0x564
# pragma option pop
#endif
} // namespace boost
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
#endif

View File

@ -23,6 +23,13 @@
# include <bits/atomicity.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using libstdc++ atomic_count")
#endif
namespace boost
{

View File

@ -13,6 +13,13 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/x86 atomic_count")
#endif
namespace boost
{

View File

@ -15,6 +15,13 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using single-threaded, non-atomic atomic_count")
#endif
namespace boost
{

View File

@ -14,6 +14,13 @@
#include <boost/assert.hpp>
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex atomic_count")
#endif
//
// The generic pthread_mutex-based implementation sometimes leads to
// inefficiencies. Example: a class with two atomic_count members

View File

@ -15,6 +15,13 @@
#include <atomic.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Solaris atomic_count")
#endif
namespace boost
{

View File

@ -13,6 +13,13 @@
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using spinlock-based atomic_count")
#endif
namespace boost
{

View File

@ -16,6 +16,13 @@
#include <atomic>
#include <cstdint>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using std::atomic atomic_count")
#endif
namespace boost
{

View File

@ -19,6 +19,13 @@
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync atomic_count")
#endif
namespace boost
{

View File

@ -19,6 +19,13 @@
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 atomic_count")
#endif
namespace boost
{

View File

@ -0,0 +1,188 @@
#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/detail/lightweight_thread.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2008, 2018 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
//
// typedef /*...*/ lw_thread_t; // as pthread_t
// template<class F> int lw_thread_create( lw_thread_t & th, F f );
// void lw_thread_join( lw_thread_t th );
#include <boost/config.hpp>
#include <memory>
#include <cerrno>
#if defined( BOOST_HAS_PTHREADS )
#include <pthread.h>
namespace boost
{
namespace detail
{
typedef ::pthread_t lw_thread_t;
inline int lw_thread_create_( lw_thread_t* thread, const pthread_attr_t* attr, void* (*start_routine)( void* ), void* arg )
{
return ::pthread_create( thread, attr, start_routine, arg );
}
inline void lw_thread_join( lw_thread_t th )
{
::pthread_join( th, 0 );
}
} // namespace detail
} // namespace boost
#else // defined( BOOST_HAS_PTHREADS )
#include <windows.h>
#include <process.h>
namespace boost
{
namespace detail
{
typedef HANDLE lw_thread_t;
inline int lw_thread_create_( lw_thread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
{
HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
if( h != 0 )
{
*thread = h;
return 0;
}
else
{
return EAGAIN;
}
}
inline void lw_thread_join( lw_thread_t thread )
{
::WaitForSingleObject( thread, INFINITE );
::CloseHandle( thread );
}
} // namespace detail
} // namespace boost
#endif // defined( BOOST_HAS_PTHREADS )
namespace boost
{
namespace detail
{
class lw_abstract_thread
{
public:
virtual ~lw_abstract_thread() {}
virtual void run() = 0;
};
#if defined( BOOST_HAS_PTHREADS )
extern "C" void * lw_thread_routine( void * pv )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#else
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#endif
pt->run();
return 0;
}
#else
unsigned __stdcall lw_thread_routine( void * pv )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#else
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#endif
pt->run();
return 0;
}
#endif
template<class F> class lw_thread_impl: public lw_abstract_thread
{
public:
explicit lw_thread_impl( F f ): f_( f )
{
}
void run()
{
f_();
}
private:
F f_;
};
template<class F> int lw_thread_create( lw_thread_t & th, F f )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
#else
std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
#endif
int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() );
if( r == 0 )
{
p.release();
}
return r;
}
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED

View File

@ -113,12 +113,12 @@ public:
#endif
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
delete this;
}
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return pn_;
}
@ -130,12 +130,12 @@ public:
shared_count pn_;
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
shared_count().swap( pn_ );
}
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return pn_;
}

View File

@ -18,32 +18,29 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifdef __BORLANDC__
#if defined(__BORLANDC__) && !defined(__clang__)
# pragma warn -8027 // Functions containing try are not expanded inline
#endif
#include <boost/config.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/bad_weak_ptr.hpp>
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/core/addressof.hpp>
#include <boost/config.hpp>
#include <boost/config/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
#include <boost/cstdint.hpp>
#include <memory> // std::auto_ptr
#include <functional> // std::less
#include <cstddef> // std::size_t
#ifdef BOOST_NO_EXCEPTIONS
# include <new> // std::bad_alloc
#endif
#include <boost/core/addressof.hpp>
#if defined( BOOST_SP_DISABLE_DEPRECATED )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@ -103,6 +100,14 @@ template< class D > struct sp_convert_reference< D& >
typedef sp_reference_wrapper< D > type;
};
template<class T> std::size_t sp_hash_pointer( T* p ) BOOST_NOEXCEPT
{
boost::uintptr_t v = reinterpret_cast<boost::uintptr_t>( p );
// match boost::hash<T*>
return static_cast<std::size_t>( v + ( v >> 3 ) );
}
class weak_count;
class shared_count
@ -489,16 +494,20 @@ public:
return pi_ == 0;
}
friend inline bool operator==(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT
bool operator==( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return a.pi_ == b.pi_;
return pi_ == r.pi_;
}
friend inline bool operator<(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT
bool operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT;
bool operator<( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
bool operator<( weak_count const & r ) const BOOST_SP_NOEXCEPT;
void * get_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pi_? pi_->get_deleter( ti ): 0;
@ -513,6 +522,11 @@ public:
{
return pi_? pi_->get_untyped_deleter(): 0;
}
std::size_t hash_value() const BOOST_SP_NOEXCEPT
{
return sp_hash_pointer( pi_ );
}
};
@ -620,14 +634,29 @@ public:
return pi_ == 0;
}
friend inline bool operator==(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT
bool operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return a.pi_ == b.pi_;
return pi_ == r.pi_;
}
friend inline bool operator<(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT
bool operator==( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
return pi_ == r.pi_;
}
bool operator<( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
bool operator<( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
std::size_t hash_value() const BOOST_SP_NOEXCEPT
{
return sp_hash_pointer( pi_ );
}
};
@ -653,6 +682,16 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_
}
}
inline bool shared_count::operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return pi_ == r.pi_;
}
inline bool shared_count::operator<( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
} // namespace detail
} // namespace boost
@ -661,7 +700,7 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_
#pragma GCC diagnostic pop
#endif
#ifdef __BORLANDC__
#if defined(__BORLANDC__) && !defined(__clang__)
# pragma warn .8027 // Functions containing try are not expanded inline
#endif

View File

@ -26,7 +26,7 @@
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_BORLANDC ) && ( BOOST_BORLANDC < 0x630 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif

View File

@ -19,6 +19,13 @@
#include <boost/config.hpp>
#include <machine/sys/inline.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using HP aCC++/HP-UX/IA64 sp_counted_base")
#endif
namespace boost
{

View File

@ -25,6 +25,13 @@
#include <builtins.h>
#include <sys/atomic_op.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using AIX sp_counted_base")
#endif
namespace boost
{

View File

@ -20,12 +20,29 @@
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Clang/C11 sp_counted_base")
#endif
namespace boost
{
namespace detail
{
#if defined(__clang__)
# pragma clang diagnostic push
#endif
#if defined(__clang__) && defined(__has_warning)
# if __has_warning( "-Wc11-extensions" )
# pragma clang diagnostic ignored "-Wc11-extensions"
# endif
#endif
typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
inline void atomic_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
@ -61,7 +78,6 @@ inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t *
}
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wweak-vtables"
#endif

View File

@ -27,6 +27,13 @@
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using CodeWarrior/PowerPC sp_counted_base")
#endif
namespace boost
{

View File

@ -28,6 +28,13 @@
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using CodeWarrior/x86 sp_counted_base")
#endif
namespace boost
{

View File

@ -19,6 +19,13 @@
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/IA64 sp_counted_base")
#endif
namespace boost
{

View File

@ -23,6 +23,13 @@
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/MIPS sp_counted_base")
#endif
namespace boost
{

View File

@ -27,6 +27,13 @@
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/PowerPC sp_counted_base")
#endif
namespace boost
{

View File

@ -23,6 +23,13 @@
#include <boost/config.hpp>
#include <inttypes.h> // int32_t
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/Sparc sp_counted_base")
#endif
namespace boost
{

View File

@ -27,6 +27,13 @@
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/x86 sp_counted_base")
#endif
namespace boost
{

View File

@ -23,6 +23,13 @@
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using single-threaded, non-atomic sp_counted_base")
#endif
namespace boost
{

View File

@ -24,6 +24,13 @@
#include <boost/cstdint.hpp>
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex sp_counted_base")
#endif
namespace boost
{

View File

@ -6,7 +6,7 @@
# pragma once
#endif
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
// detail/sp_counted_base_gcc_snc_ps3.hpp - PS3 Cell
//
// Copyright (c) 2006 Piotr Wyderski
// Copyright (c) 2006 Tomas Puverle
@ -23,6 +23,13 @@
#include <boost/config.hpp>
#include <inttypes.h> // uint32_t
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using PS3 sp_counted_base")
#endif
namespace boost
{

View File

@ -24,6 +24,13 @@
#include <boost/config.hpp>
#include <atomic.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Solaris sp_counted_base")
#endif
namespace boost
{

View File

@ -22,6 +22,13 @@
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using spinlock-based sp_counted_base")
#endif
namespace boost
{

View File

@ -21,6 +21,13 @@
#include <atomic>
#include <cstdint>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using std::atomic sp_counted_base")
#endif
namespace boost
{

View File

@ -23,6 +23,13 @@
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync sp_counted_base")
#endif
namespace boost
{

View File

@ -24,6 +24,13 @@
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using xlC/PowerPC sp_counted_base")
#endif
extern "builtin" void __lwsync(void);
extern "builtin" void __isync(void);
extern "builtin" int __fetch_and_add(volatile int* addr, int val);

View File

@ -29,6 +29,13 @@
#include <boost/config/workaround.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 sp_counted_base")
#endif
namespace boost
{

View File

@ -18,25 +18,21 @@
// 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>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/checked_delete.hpp>
#include <boost/core/addressof.hpp>
#include <boost/config.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 <memory> // std::allocator, std::allocator_traits
#include <cstddef> // std::size_t
namespace boost
@ -85,7 +81,7 @@ public:
#endif
}
virtual void dispose() BOOST_SP_NOEXCEPT
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
@ -93,17 +89,17 @@ public:
boost::checked_delete( px_ );
}
virtual void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT
void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
virtual void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT
void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
@ -168,22 +164,22 @@ public:
{
}
virtual void dispose() BOOST_SP_NOEXCEPT
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
del( ptr );
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT
void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0;
}
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT
void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
}
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return &reinterpret_cast<char&>( del );
}
@ -242,12 +238,12 @@ public:
{
}
virtual void dispose() BOOST_SP_NOEXCEPT
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
d_( p_ );
}
virtual void destroy() BOOST_SP_NOEXCEPT
void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
@ -266,17 +262,17 @@ public:
a2.deallocate( this, 1 );
}
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT
void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0;
}
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT
void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
}
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return &reinterpret_cast<char&>( d_ );
}

View File

@ -11,6 +11,13 @@
#include <boost/smart_ptr/detail/yield_k.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/ARM spinlock")
#endif
#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"

View File

@ -17,6 +17,13 @@
#include <boost/assert.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using single-threaded spinlock emulation")
#endif
namespace boost
{

View File

@ -17,6 +17,13 @@
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex spinlock emulation")
#endif
namespace boost
{

View File

@ -19,6 +19,13 @@
#include <boost/config.hpp>
#include <atomic>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using std::atomic spinlock")
#endif
namespace boost
{

View File

@ -21,6 +21,13 @@
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync spinlock")
#endif
namespace boost
{

View File

@ -18,6 +18,13 @@
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
#include <boost/smart_ptr/detail/yield_k.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 spinlock")
#endif
// BOOST_COMPILER_FENCE
#if defined(__INTEL_COMPILER)

View File

@ -385,4 +385,23 @@ template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
} // namespace boost
// std::hash
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
namespace std
{
template<class T> struct hash< ::boost::intrusive_ptr<T> >
{
std::size_t operator()( ::boost::intrusive_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return std::hash< T* >()( p.get() );
}
};
} // namespace std
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED

View File

@ -494,6 +494,13 @@ public:
{
return std::less< boost::detail::local_counted_base* >()( pn, r.pn );
}
// owner_equals
template<class Y> bool owner_equals( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
{
return pn == r.pn;
}
};
template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
@ -681,4 +688,23 @@ template< class T > std::size_t hash_value( local_shared_ptr<T> const & p ) BOOS
} // namespace boost
// std::hash
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
namespace std
{
template<class T> struct hash< ::boost::local_shared_ptr<T> >
{
std::size_t operator()( ::boost::local_shared_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return std::hash< typename ::boost::local_shared_ptr<T>::element_type* >()( p.get() );
}
};
} // namespace std
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#endif // #ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED

View File

@ -187,7 +187,7 @@ template< class T > struct sp_if_not_array< T[] >
{
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_if_not_array< T[N] >
{

View File

@ -0,0 +1,27 @@
#ifndef BOOST_SMART_PTR_OWNER_EQUAL_TO_HPP_INCLUDED
#define BOOST_SMART_PTR_OWNER_EQUAL_TO_HPP_INCLUDED
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
namespace boost
{
template<class T = void> struct owner_equal_to
{
typedef bool result_type;
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const BOOST_NOEXCEPT
{
return u.owner_equals( v );
}
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_OWNER_EQUAL_TO_HPP_INCLUDED

View File

@ -0,0 +1,27 @@
#ifndef BOOST_SMART_PTR_OWNER_HASH_HPP_INCLUDED
#define BOOST_SMART_PTR_OWNER_HASH_HPP_INCLUDED
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <cstddef>
namespace boost
{
template<class T> struct owner_hash
{
typedef std::size_t result_type;
typedef T argument_type;
std::size_t operator()( T const & t ) const BOOST_NOEXCEPT
{
return t.owner_hash_value();
}
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_OWNER_HASH_HPP_INCLUDED

View File

@ -14,6 +14,8 @@
// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/config.hpp>
namespace boost
{
@ -23,7 +25,7 @@ template<class T = void> struct owner_less
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const
template<class U, class V> bool operator()( U const & u, V const & v ) const BOOST_NOEXCEPT
{
return u.owner_before( v );
}

View File

@ -14,23 +14,16 @@
// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/config.hpp> // for broken compiler workarounds
// In order to avoid circular dependencies with Boost.TR1
// we make sure that our include of <memory> doesn't try to
// pull in the TR1 headers: that's why we use this header
// rather than including <memory> directly:
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/config/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
@ -40,6 +33,7 @@
#include <functional> // for std::less
#include <typeinfo> // for std::bad_cast
#include <cstddef> // for std::size_t
#include <memory> // for std::auto_ptr
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
@ -86,7 +80,7 @@ template< class T > struct sp_element< T[] >
typedef T type;
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_element< T[N] >
{
@ -135,7 +129,7 @@ template< class T > struct sp_dereference< T[] >
typedef void type;
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_dereference< T[N] >
{
@ -160,7 +154,7 @@ template< class T > struct sp_member_access< T[] >
typedef void type;
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_member_access< T[N] >
{
@ -185,7 +179,7 @@ template< class T > struct sp_array_access< T[] >
typedef T & type;
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_array_access< T[N] >
{
@ -777,6 +771,21 @@ public:
return pn < rhs.pn;
}
template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn == rhs.pn;
}
template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn == rhs.pn;
}
std::size_t owner_hash_value() const BOOST_SP_NOEXCEPT
{
return pn.hash_value();
}
void * _internal_get_deleter( boost::detail::sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pn.get_deleter( ti );
@ -1155,6 +1164,25 @@ template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOO
} // namespace boost
// std::hash
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
namespace std
{
template<class T> struct hash< ::boost::shared_ptr<T> >
{
std::size_t operator()( ::boost::shared_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return std::hash< typename ::boost::shared_ptr<T>::element_type* >()( p.get() );
}
};
} // namespace std
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#include <boost/smart_ptr/detail/local_sp_deleter.hpp>
namespace boost

View File

@ -13,10 +13,11 @@
// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <memory> // boost.TR1 include order fix
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <memory>
#include <cstddef>
namespace boost
{
@ -237,6 +238,21 @@ public:
return pn < rhs.pn;
}
template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn == rhs.pn;
}
template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn == rhs.pn;
}
std::size_t owner_hash_value() const BOOST_SP_NOEXCEPT
{
return pn.hash_value();
}
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)
@ -270,6 +286,40 @@ template<class T> weak_ptr( shared_ptr<T> ) -> weak_ptr<T>;
#endif
// hash_value
template< class T > std::size_t hash_value( boost::weak_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.owner_hash_value();
}
} // namespace boost
// std::hash, std::equal_to
namespace std
{
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
template<class T> struct hash< ::boost::weak_ptr<T> >
{
std::size_t operator()( ::boost::weak_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return p.owner_hash_value();
}
};
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
template<class T> struct equal_to< ::boost::weak_ptr<T> >
{
bool operator()( ::boost::weak_ptr<T> const & a, ::boost::weak_ptr<T> const & b ) const BOOST_SP_NOEXCEPT
{
return a.owner_equals( b );
}
};
} // namespace std
#endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED

View File

@ -10,6 +10,6 @@ if(HAVE_BOOST_TEST)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::smart_ptr Boost::core Boost::align Boost::atomic Boost::container_hash Threads::Threads)
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::smart_ptr Boost::core Boost::align Boost::atomic Boost::container_hash Boost::bind Threads::Threads)
endif()

View File

@ -359,3 +359,52 @@ run wp_guides_test.cpp ;
compile-fail shared_from_fail.cpp ;
compile-fail weak_from_fail.cpp ;
compile sp_override_test.cpp ;
compile sp_pedantic_test.cpp
: <warnings>pedantic
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on ;
run sp_owner_before_test.cpp ;
run sp_owner_equals_test.cpp ;
run lsp_owner_before_test.cpp ;
run lsp_owner_equals_test.cpp ;
run owner_equal_to_test.cpp ;
run owner_equal_to_test2.cpp ;
run owner_less_test2.cpp ;
run ip_hash_test2.cpp ;
run sp_hash_test4.cpp ;
run lsp_hash_test.cpp ;
run lsp_hash_test2.cpp ;
run atomic_count_mt_test.cpp
: : : <threading>multi ;
run spinlock_mt_test.cpp
: : : <threading>multi ;
run spinlock_pool_mt_test.cpp
: : : <threading>multi ;
run shared_ptr_mt_test.cpp
: : : <threading>multi ;
run weak_ptr_mt_test.cpp
: : : <threading>multi ;
compile sp_report_implementation.cpp ;
run sp_owner_hash_value_test.cpp ;
run wp_hash_test.cpp ;
run wp_hash_test2.cpp ;
run wp_unordered_test.cpp ;
run owner_hash_test.cpp ;
run sp_unordered_test.cpp ;

View File

@ -0,0 +1,40 @@
// Copyright 2018, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/smart_ptr/detail/atomic_count.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <boost/bind/bind.hpp>
#include <boost/core/lightweight_test.hpp>
static boost::detail::atomic_count count( 0 );
void f( int n )
{
for( int i = 0; i < n; ++i )
{
++count;
}
}
int main()
{
int const N = 100000; // iterations
int const M = 8; // threads
boost::detail::lw_thread_t th[ M ] = {};
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_create( th[ i ], boost::bind( f, N ) );
}
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_join( th[ i ] );
}
BOOST_TEST_EQ( count, N * M );
return boost::report_errors();
}

67
test/ip_hash_test2.cpp Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2011, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/intrusive_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <functional>
#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
int main() {}
#else
class base
{
private:
int use_count_;
base(base const &);
base & operator=(base const &);
protected:
base(): use_count_(0)
{
}
virtual ~base()
{
}
public:
long use_count() const
{
return use_count_;
}
inline friend void intrusive_ptr_add_ref(base * p)
{
++p->use_count_;
}
inline friend void intrusive_ptr_release(base * p)
{
if(--p->use_count_ == 0) delete p;
}
};
struct X: public base
{
};
int main()
{
boost::intrusive_ptr<X> p1, p2( new X );
BOOST_TEST_EQ( std::hash< boost::intrusive_ptr<X> >()( p1 ), std::hash< X* >()( p1.get() ) );
BOOST_TEST_EQ( std::hash< boost::intrusive_ptr<X> >()( p2 ), std::hash< X* >()( p2.get() ) );
return boost::report_errors();
}
#endif // #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)

66
test/lsp_hash_test.cpp Normal file
View File

@ -0,0 +1,66 @@
// Copyright 2011, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/functional/hash.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
{
boost::hash< boost::local_shared_ptr<int> > hasher;
boost::local_shared_ptr<int> p1, p2( p1 ), p3( new int ), p4( p3 ), p5( new int );
BOOST_TEST_EQ( p1, p2 );
BOOST_TEST_EQ( hasher( p1 ), hasher( p2 ) );
BOOST_TEST_NE( p1, p3 );
BOOST_TEST_NE( hasher( p1 ), hasher( p3 ) );
BOOST_TEST_EQ( p3, p4 );
BOOST_TEST_EQ( hasher( p3 ), hasher( p4 ) );
BOOST_TEST_NE( p3, p5 );
BOOST_TEST_NE( hasher( p3 ), hasher( p5 ) );
}
{
boost::hash< boost::local_shared_ptr<int[]> > hasher;
boost::local_shared_ptr<int[]> p1, p2( p1 ), p3( new int[1] ), p4( p3 ), p5( new int[1] );
BOOST_TEST_EQ( p1, p2 );
BOOST_TEST_EQ( hasher( p1 ), hasher( p2 ) );
BOOST_TEST_NE( p1, p3 );
BOOST_TEST_NE( hasher( p1 ), hasher( p3 ) );
BOOST_TEST_EQ( p3, p4 );
BOOST_TEST_EQ( hasher( p3 ), hasher( p4 ) );
BOOST_TEST_NE( p3, p5 );
BOOST_TEST_NE( hasher( p3 ), hasher( p5 ) );
}
{
boost::hash< boost::local_shared_ptr<int[1]> > hasher;
boost::local_shared_ptr<int[1]> p1, p2( p1 ), p3( new int[1] ), p4( p3 ), p5( new int[1] );
BOOST_TEST_EQ( p1, p2 );
BOOST_TEST_EQ( hasher( p1 ), hasher( p2 ) );
BOOST_TEST_NE( p1, p3 );
BOOST_TEST_NE( hasher( p1 ), hasher( p3 ) );
BOOST_TEST_EQ( p3, p4 );
BOOST_TEST_EQ( hasher( p3 ), hasher( p4 ) );
BOOST_TEST_NE( p3, p5 );
BOOST_TEST_NE( hasher( p3 ), hasher( p5 ) );
}
return boost::report_errors();
}

42
test/lsp_hash_test2.cpp Normal file
View File

@ -0,0 +1,42 @@
// Copyright 2011, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <functional>
#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
int main() {}
#else
int main()
{
{
boost::local_shared_ptr<int> p1, p2( new int );
BOOST_TEST_EQ( std::hash< boost::local_shared_ptr<int> >()( p1 ), std::hash< int* >()( p1.get() ) );
BOOST_TEST_EQ( std::hash< boost::local_shared_ptr<int> >()( p2 ), std::hash< int* >()( p2.get() ) );
}
{
boost::local_shared_ptr<int[]> p1, p2( new int[1] );
BOOST_TEST_EQ( std::hash< boost::local_shared_ptr<int[]> >()( p1 ), std::hash< int* >()( p1.get() ) );
BOOST_TEST_EQ( std::hash< boost::local_shared_ptr<int[]> >()( p2 ), std::hash< int* >()( p2.get() ) );
}
{
boost::local_shared_ptr<int[1]> p1, p2( new int[1] );
BOOST_TEST_EQ( std::hash< boost::local_shared_ptr<int[1]> >()( p1 ), std::hash< int* >()( p1.get() ) );
BOOST_TEST_EQ( std::hash< boost::local_shared_ptr<int[1]> >()( p2 ), std::hash< int* >()( p2.get() ) );
}
return boost::report_errors();
}
#endif // #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)

View File

@ -0,0 +1,103 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
{
boost::local_shared_ptr<int> p1( new int );
boost::local_shared_ptr<int> p2( p1 );
BOOST_TEST( !p1.owner_before( p2 ) );
BOOST_TEST( !p2.owner_before( p1 ) );
boost::local_shared_ptr<int> p3( new int );
BOOST_TEST( p1.owner_before( p3 ) || p3.owner_before( p1 ) );
boost::local_shared_ptr<int> p4;
boost::local_shared_ptr<int> p5;
BOOST_TEST( !p4.owner_before( p5 ) );
BOOST_TEST( !p5.owner_before( p4 ) );
BOOST_TEST( p4.owner_before( p3 ) || p3.owner_before( p4 ) );
boost::local_shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST( p4.owner_before( p6 ) || p6.owner_before( p4 ) );
boost::local_shared_ptr<void> p7( p1 );
BOOST_TEST( !p1.owner_before( p7 ) );
BOOST_TEST( !p7.owner_before( p1 ) );
boost::local_shared_ptr<void> p8;
BOOST_TEST( p1.owner_before( p8 ) || p8.owner_before( p1 ) );
BOOST_TEST( !p4.owner_before( p8 ) );
BOOST_TEST( !p8.owner_before( p4 ) );
/*
boost::local_weak_ptr<int> q1( p1 );
BOOST_TEST( !p1.owner_before( q1 ) );
BOOST_TEST( !q1.owner_before( p1 ) );
boost::local_weak_ptr<int> q2( p1 );
BOOST_TEST( !q1.owner_before( q2 ) );
BOOST_TEST( !q2.owner_before( q1 ) );
boost::local_weak_ptr<int> q3( p3 );
BOOST_TEST( p1.owner_before( q3 ) || q3.owner_before( p1 ) );
BOOST_TEST( q1.owner_before( q3 ) || q3.owner_before( q1 ) );
boost::local_weak_ptr<int> q4;
BOOST_TEST( !p4.owner_before( q4 ) );
BOOST_TEST( !q4.owner_before( p4 ) );
BOOST_TEST( q1.owner_before( q4 ) || q4.owner_before( q1 ) );
boost::local_weak_ptr<void> q5;
BOOST_TEST( !q4.owner_before( q5 ) );
BOOST_TEST( !q5.owner_before( q4 ) );
boost::local_weak_ptr<void> q7( p7 );
BOOST_TEST( !p1.owner_before( q7 ) );
BOOST_TEST( !q7.owner_before( p1 ) );
BOOST_TEST( !q1.owner_before( q7 ) );
BOOST_TEST( !q7.owner_before( q1 ) );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST( !q1.owner_before( q2 ) );
BOOST_TEST( !q2.owner_before( q1 ) );
BOOST_TEST( !q1.owner_before( q7 ) );
BOOST_TEST( !q7.owner_before( q1 ) );
BOOST_TEST( q1.owner_before( q3 ) || q3.owner_before( q1 ) );
BOOST_TEST( q1.owner_before( q4 ) || q4.owner_before( q1 ) );
*/
}
return boost::report_errors();
}

View File

@ -0,0 +1,113 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
{
boost::local_shared_ptr<int> p1( new int );
boost::local_shared_ptr<int> p2( p1 );
BOOST_TEST( p1.owner_equals( p2 ) );
BOOST_TEST( p2.owner_equals( p1 ) );
boost::local_shared_ptr<int> p3( new int );
BOOST_TEST( !p1.owner_equals( p3 ) );
BOOST_TEST( !p3.owner_equals( p1 ) );
boost::local_shared_ptr<int> p4;
boost::local_shared_ptr<int> p5;
BOOST_TEST( p4.owner_equals( p5 ) );
BOOST_TEST( p5.owner_equals( p4 ) );
BOOST_TEST( !p4.owner_equals( p3 ) );
BOOST_TEST( !p3.owner_equals( p4 ) );
boost::local_shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST( !p4.owner_equals( p6 ) );
BOOST_TEST( !p6.owner_equals( p4 ) );
boost::local_shared_ptr<void> p7( p1 );
BOOST_TEST( p1.owner_equals( p7 ) );
BOOST_TEST( p7.owner_equals( p1 ) );
boost::local_shared_ptr<void> p8;
BOOST_TEST( !p1.owner_equals( p8 ) );
BOOST_TEST( !p8.owner_equals( p1 ) );
BOOST_TEST( p4.owner_equals( p8 ) );
BOOST_TEST( p8.owner_equals( p4 ) );
/*
boost::local_weak_ptr<int> q1( p1 );
BOOST_TEST( p1.owner_equals( q1 ) );
BOOST_TEST( q1.owner_equals( p1 ) );
boost::local_weak_ptr<int> q2( p1 );
BOOST_TEST( q1.owner_equals( q2 ) );
BOOST_TEST( q2.owner_equals( q1 ) );
boost::local_weak_ptr<int> q3( p3 );
BOOST_TEST( !p1.owner_equals( q3 ) );
BOOST_TEST( !q3.owner_equals( p1 ) );
BOOST_TEST( !q1.owner_equals( q3 ) );
BOOST_TEST( !q3.owner_equals( q1 ) );
boost::local_weak_ptr<int> q4;
BOOST_TEST( p4.owner_equals( q4 ) );
BOOST_TEST( q4.owner_equals( p4 ) );
BOOST_TEST( !q1.owner_equals( q4 ) );
BOOST_TEST( !q4.owner_equals( q1 ) );
boost::local_weak_ptr<void> q5;
BOOST_TEST( q4.owner_equals( q5 ) );
BOOST_TEST( q5.owner_equals( q4 ) );
boost::local_weak_ptr<void> q7( p7 );
BOOST_TEST( p1.owner_equals( q7 ) );
BOOST_TEST( q7.owner_equals( p1 ) );
BOOST_TEST( q1.owner_equals( q7 ) );
BOOST_TEST( q7.owner_equals( q1 ) );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST( q1.owner_equals( q2 ) );
BOOST_TEST( q2.owner_equals( q1 ) );
BOOST_TEST( q1.owner_equals( q7 ) );
BOOST_TEST( q7.owner_equals( q1 ) );
BOOST_TEST( !q1.owner_equals( q3 ) );
BOOST_TEST( !q3.owner_equals( q1 ) );
BOOST_TEST( !q1.owner_equals( q4 ) );
BOOST_TEST( !q4.owner_equals( q1 ) );
*/
}
return boost::report_errors();
}

View File

@ -0,0 +1,116 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/owner_equal_to.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
boost::owner_equal_to<> const eq = {};
{
boost::shared_ptr<int> p1( new int );
boost::shared_ptr<int> p2( p1 );
BOOST_TEST( eq( p1, p2 ) );
BOOST_TEST( eq( p2, p1 ) );
boost::shared_ptr<int> p3( new int );
BOOST_TEST( !eq( p1, p3 ) );
BOOST_TEST( !eq( p3, p1 ) );
boost::shared_ptr<int> p4;
boost::shared_ptr<int> p5;
BOOST_TEST( eq( p4, p5 ) );
BOOST_TEST( eq( p5, p4 ) );
BOOST_TEST( !eq( p4, p3 ) );
BOOST_TEST( !eq( p3, p4 ) );
boost::shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST( !eq( p4, p6 ) );
BOOST_TEST( !eq( p6, p4 ) );
boost::shared_ptr<void> p7( p1 );
BOOST_TEST( eq( p1, p7 ) );
BOOST_TEST( eq( p7, p1 ) );
boost::shared_ptr<void> p8;
BOOST_TEST( !eq( p1, p8 ) );
BOOST_TEST( !eq( p8, p1 ) );
BOOST_TEST( eq( p4, p8 ) );
BOOST_TEST( eq( p8, p4 ) );
boost::weak_ptr<int> q1( p1 );
BOOST_TEST( eq( p1, q1 ) );
BOOST_TEST( eq( q1, p1 ) );
boost::weak_ptr<int> q2( p1 );
BOOST_TEST( eq( q1, q2 ) );
BOOST_TEST( eq( q2, q1 ) );
boost::weak_ptr<int> q3( p3 );
BOOST_TEST( !eq( p1, q3 ) );
BOOST_TEST( !eq( q3, p1 ) );
BOOST_TEST( !eq( q1, q3 ) );
BOOST_TEST( !eq( q3, q1 ) );
boost::weak_ptr<int> q4;
BOOST_TEST( eq( p4, q4 ) );
BOOST_TEST( eq( q4, p4 ) );
BOOST_TEST( !eq( q1, q4 ) );
BOOST_TEST( !eq( q4, q1 ) );
boost::weak_ptr<void> q5;
BOOST_TEST( eq( q4, q5 ) );
BOOST_TEST( eq( q5, q4 ) );
boost::weak_ptr<void> q7( p7 );
BOOST_TEST( eq( p1, q7 ) );
BOOST_TEST( eq( q7, p1 ) );
BOOST_TEST( eq( q1, q7 ) );
BOOST_TEST( eq( q7, q1 ) );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST( eq( q1, q2 ) );
BOOST_TEST( eq( q2, q1 ) );
BOOST_TEST( eq( q1, q7 ) );
BOOST_TEST( eq( q7, q1 ) );
BOOST_TEST( !eq( q1, q3 ) );
BOOST_TEST( !eq( q3, q1 ) );
BOOST_TEST( !eq( q1, q4 ) );
BOOST_TEST( !eq( q4, q1 ) );
}
return boost::report_errors();
}

View File

@ -0,0 +1,116 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/owner_equal_to.hpp>
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
boost::owner_equal_to<> const eq = {};
{
boost::local_shared_ptr<int> p1( new int );
boost::local_shared_ptr<int> p2( p1 );
BOOST_TEST( eq( p1, p2 ) );
BOOST_TEST( eq( p2, p1 ) );
boost::local_shared_ptr<int> p3( new int );
BOOST_TEST( !eq( p1, p3 ) );
BOOST_TEST( !eq( p3, p1 ) );
boost::local_shared_ptr<int> p4;
boost::local_shared_ptr<int> p5;
BOOST_TEST( eq( p4, p5 ) );
BOOST_TEST( eq( p5, p4 ) );
BOOST_TEST( !eq( p4, p3 ) );
BOOST_TEST( !eq( p3, p4 ) );
boost::local_shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST( !eq( p4, p6 ) );
BOOST_TEST( !eq( p6, p4 ) );
boost::local_shared_ptr<void> p7( p1 );
BOOST_TEST( eq( p1, p7 ) );
BOOST_TEST( eq( p7, p1 ) );
boost::local_shared_ptr<void> p8;
BOOST_TEST( !eq( p1, p8 ) );
BOOST_TEST( !eq( p8, p1 ) );
BOOST_TEST( eq( p4, p8 ) );
BOOST_TEST( eq( p8, p4 ) );
/*
boost::local_weak_ptr<int> q1( p1 );
BOOST_TEST( eq( p1, q1 ) );
BOOST_TEST( eq( q1, p1 ) );
boost::local_weak_ptr<int> q2( p1 );
BOOST_TEST( eq( q1, q2 ) );
BOOST_TEST( eq( q2, q1 ) );
boost::local_weak_ptr<int> q3( p3 );
BOOST_TEST( !eq( p1, q3 ) );
BOOST_TEST( !eq( q3, p1 ) );
BOOST_TEST( !eq( q1, q3 ) );
BOOST_TEST( !eq( q3, q1 ) );
boost::local_weak_ptr<int> q4;
BOOST_TEST( eq( p4, q4 ) );
BOOST_TEST( eq( q4, p4 ) );
BOOST_TEST( !eq( q1, q4 ) );
BOOST_TEST( !eq( q4, q1 ) );
boost::local_weak_ptr<void> q5;
BOOST_TEST( eq( q4, q5 ) );
BOOST_TEST( eq( q5, q4 ) );
boost::local_weak_ptr<void> q7( p7 );
BOOST_TEST( eq( p1, q7 ) );
BOOST_TEST( eq( q7, p1 ) );
BOOST_TEST( eq( q1, q7 ) );
BOOST_TEST( eq( q7, q1 ) );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST( eq( q1, q2 ) );
BOOST_TEST( eq( q2, q1 ) );
BOOST_TEST( eq( q1, q7 ) );
BOOST_TEST( eq( q7, q1 ) );
BOOST_TEST( !eq( q1, q3 ) );
BOOST_TEST( !eq( q3, q1 ) );
BOOST_TEST( !eq( q1, q4 ) );
BOOST_TEST( !eq( q4, q1 ) );
*/
}
return boost::report_errors();
}

88
test/owner_hash_test.cpp Normal file
View File

@ -0,0 +1,88 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/owner_hash.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T> std::size_t hash_( T const& t )
{
return boost::owner_hash<T>()( t );
}
int main()
{
boost::shared_ptr<int> p1( new int );
boost::shared_ptr<int> p2( p1 );
BOOST_TEST_EQ( hash_( p1 ), hash_( p2 ) );
boost::shared_ptr<int> p3( new int );
BOOST_TEST_NE( hash_( p1 ), hash_( p3 ) );
boost::shared_ptr<int> p4;
boost::shared_ptr<int> p5;
BOOST_TEST_EQ( hash_( p4 ), hash_( p5 ) );
BOOST_TEST_NE( hash_( p4 ), hash_( p3 ) );
boost::shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST_NE( hash_( p4 ), hash_( p6 ) );
boost::shared_ptr<void> p7( p1 );
BOOST_TEST_EQ( hash_( p1 ), hash_( p7 ) );
boost::shared_ptr<void> p8;
BOOST_TEST_NE( hash_( p1 ), hash_( p8 ) );
BOOST_TEST_EQ( hash_( p4 ), hash_( p8 ) );
boost::weak_ptr<int> q1( p1 );
BOOST_TEST_EQ( hash_( p1 ), hash_( q1 ) );
boost::weak_ptr<int> q2( p1 );
BOOST_TEST_EQ( hash_( q1 ), hash_( q2 ) );
boost::weak_ptr<int> q3( p3 );
BOOST_TEST_NE( hash_( p1 ), hash_( q3 ) );
BOOST_TEST_NE( hash_( q1 ), hash_( q3 ) );
boost::weak_ptr<int> q4;
BOOST_TEST_EQ( hash_( p4 ), hash_( q4 ) );
BOOST_TEST_NE( hash_( q1 ), hash_( q4 ) );
boost::weak_ptr<void> q5;
BOOST_TEST_EQ( hash_( q4 ), hash_( q5 ) );
boost::weak_ptr<void> q7( p7 );
BOOST_TEST_EQ( hash_( p1 ), hash_( q7 ) );
BOOST_TEST_EQ( hash_( q1 ), hash_( q7 ) );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST_EQ( hash_( q1 ), hash_( q2 ) );
BOOST_TEST_EQ( hash_( q1 ), hash_( q7 ) );
BOOST_TEST_NE( hash_( q1 ), hash_( q3 ) );
BOOST_TEST_NE( hash_( q1 ), hash_( q4 ) );
return boost::report_errors();
}

106
test/owner_less_test2.cpp Normal file
View File

@ -0,0 +1,106 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/owner_less.hpp>
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
boost::owner_less<> const lt = {};
{
boost::local_shared_ptr<int> p1( new int );
boost::local_shared_ptr<int> p2( p1 );
BOOST_TEST( !lt( p1, p2 ) );
BOOST_TEST( !lt( p2, p1 ) );
boost::local_shared_ptr<int> p3( new int );
BOOST_TEST( lt( p1, p3 ) || lt( p3, p1 ) );
boost::local_shared_ptr<int> p4;
boost::local_shared_ptr<int> p5;
BOOST_TEST( !lt( p4, p5 ) );
BOOST_TEST( !lt( p5, p4 ) );
BOOST_TEST( lt( p4, p3 ) || lt( p3, p4 ) );
boost::local_shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST( lt( p4, p6 ) || lt( p6, p4 ) );
boost::local_shared_ptr<void> p7( p1 );
BOOST_TEST( !lt( p1, p7 ) );
BOOST_TEST( !lt( p7, p1 ) );
boost::local_shared_ptr<void> p8;
BOOST_TEST( lt( p1, p8 ) || lt( p8, p1 ) );
BOOST_TEST( !lt( p4, p8 ) );
BOOST_TEST( !lt( p8, p4 ) );
/*
boost::local_weak_ptr<int> q1( p1 );
BOOST_TEST( !lt( p1, q1 ) );
BOOST_TEST( !lt( q1, p1 ) );
boost::local_weak_ptr<int> q2( p1 );
BOOST_TEST( !lt( q1, q2 ) );
BOOST_TEST( !lt( q2, q1 ) );
boost::local_weak_ptr<int> q3( p3 );
BOOST_TEST( lt( p1, q3 ) || lt( q3, p1 ) );
BOOST_TEST( lt( q1, q3 ) || lt( q3, q1 ) );
boost::local_weak_ptr<int> q4;
BOOST_TEST( !lt( p4, q4 ) );
BOOST_TEST( !lt( q4, p4 ) );
BOOST_TEST( lt( q1, q4 ) || lt( q4, q1 ) );
boost::local_weak_ptr<void> q5;
BOOST_TEST( !lt( q4, q5 ) );
BOOST_TEST( !lt( q5, q4 ) );
boost::local_weak_ptr<void> q7( p7 );
BOOST_TEST( !lt( p1, q7 ) );
BOOST_TEST( !lt( q7, p1 ) );
BOOST_TEST( !lt( q1, q7 ) );
BOOST_TEST( !lt( q7, q1 ) );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST( !lt( q1, q2 ) );
BOOST_TEST( !lt( q2, q1 ) );
BOOST_TEST( !lt( q1, q7 ) );
BOOST_TEST( !lt( q7, q1 ) );
BOOST_TEST( lt( q1, q3 ) || lt( q3, q1 ) );
BOOST_TEST( lt( q1, q4 ) || lt( q4, q1 ) );
*/
}
return boost::report_errors();
}

View File

@ -0,0 +1,46 @@
// Copyright 2018, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <boost/bind/bind.hpp>
#include <boost/core/lightweight_test.hpp>
static boost::shared_ptr<int> sp( new int );
void f( int n )
{
for( int i = 0; i < n; ++i )
{
boost::shared_ptr<int> p1( sp );
boost::weak_ptr<int> p2( p1 );
}
}
int main()
{
int const N = 100000; // iterations
int const M = 8; // threads
boost::detail::lw_thread_t th[ M ] = {};
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_create( th[ i ], boost::bind( f, N ) );
}
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_join( th[ i ] );
}
BOOST_TEST_EQ( sp.use_count(), 1 );
sp.reset();
BOOST_TEST_EQ( sp.use_count(), 0 );
return boost::report_errors();
}

View File

@ -31,7 +31,7 @@
#endif
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
# pragma warn -8092 // template argument passed to 'find' is not an iterator
#endif

42
test/sp_hash_test4.cpp Normal file
View File

@ -0,0 +1,42 @@
// Copyright 2011, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <functional>
#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
int main() {}
#else
int main()
{
{
boost::shared_ptr<int> p1, p2( new int );
BOOST_TEST_EQ( std::hash< boost::shared_ptr<int> >()( p1 ), std::hash< int* >()( p1.get() ) );
BOOST_TEST_EQ( std::hash< boost::shared_ptr<int> >()( p2 ), std::hash< int* >()( p2.get() ) );
}
{
boost::shared_ptr<int[]> p1, p2( new int[1] );
BOOST_TEST_EQ( std::hash< boost::shared_ptr<int[]> >()( p1 ), std::hash< int* >()( p1.get() ) );
BOOST_TEST_EQ( std::hash< boost::shared_ptr<int[]> >()( p2 ), std::hash< int* >()( p2.get() ) );
}
{
boost::shared_ptr<int[1]> p1, p2( new int[1] );
BOOST_TEST_EQ( std::hash< boost::shared_ptr<int[1]> >()( p1 ), std::hash< int* >()( p1.get() ) );
BOOST_TEST_EQ( std::hash< boost::shared_ptr<int[1]> >()( p2 ), std::hash< int* >()( p2.get() ) );
}
return boost::report_errors();
}
#endif // #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)

25
test/sp_override_test.cpp Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(__GNUC__) && __GNUC__ >= 5 && __cplusplus >= 201103L
# pragma GCC diagnostic error "-Wsuggest-override"
#endif
#include <boost/smart_ptr.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
int main()
{
boost::shared_ptr<int> p1( new int );
boost::shared_ptr<int[]> p2( new int[1] );
boost::make_shared<int>();
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1500)
boost::make_shared<int[]>( 1 );
#endif
}

View File

@ -0,0 +1,103 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
{
boost::shared_ptr<int> p1( new int );
boost::shared_ptr<int> p2( p1 );
BOOST_TEST( !p1.owner_before( p2 ) );
BOOST_TEST( !p2.owner_before( p1 ) );
boost::shared_ptr<int> p3( new int );
BOOST_TEST( p1.owner_before( p3 ) || p3.owner_before( p1 ) );
boost::shared_ptr<int> p4;
boost::shared_ptr<int> p5;
BOOST_TEST( !p4.owner_before( p5 ) );
BOOST_TEST( !p5.owner_before( p4 ) );
BOOST_TEST( p4.owner_before( p3 ) || p3.owner_before( p4 ) );
boost::shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST( p4.owner_before( p6 ) || p6.owner_before( p4 ) );
boost::shared_ptr<void> p7( p1 );
BOOST_TEST( !p1.owner_before( p7 ) );
BOOST_TEST( !p7.owner_before( p1 ) );
boost::shared_ptr<void> p8;
BOOST_TEST( p1.owner_before( p8 ) || p8.owner_before( p1 ) );
BOOST_TEST( !p4.owner_before( p8 ) );
BOOST_TEST( !p8.owner_before( p4 ) );
boost::weak_ptr<int> q1( p1 );
BOOST_TEST( !p1.owner_before( q1 ) );
BOOST_TEST( !q1.owner_before( p1 ) );
boost::weak_ptr<int> q2( p1 );
BOOST_TEST( !q1.owner_before( q2 ) );
BOOST_TEST( !q2.owner_before( q1 ) );
boost::weak_ptr<int> q3( p3 );
BOOST_TEST( p1.owner_before( q3 ) || q3.owner_before( p1 ) );
BOOST_TEST( q1.owner_before( q3 ) || q3.owner_before( q1 ) );
boost::weak_ptr<int> q4;
BOOST_TEST( !p4.owner_before( q4 ) );
BOOST_TEST( !q4.owner_before( p4 ) );
BOOST_TEST( q1.owner_before( q4 ) || q4.owner_before( q1 ) );
boost::weak_ptr<void> q5;
BOOST_TEST( !q4.owner_before( q5 ) );
BOOST_TEST( !q5.owner_before( q4 ) );
boost::weak_ptr<void> q7( p7 );
BOOST_TEST( !p1.owner_before( q7 ) );
BOOST_TEST( !q7.owner_before( p1 ) );
BOOST_TEST( !q1.owner_before( q7 ) );
BOOST_TEST( !q7.owner_before( q1 ) );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST( !q1.owner_before( q2 ) );
BOOST_TEST( !q2.owner_before( q1 ) );
BOOST_TEST( !q1.owner_before( q7 ) );
BOOST_TEST( !q7.owner_before( q1 ) );
BOOST_TEST( q1.owner_before( q3 ) || q3.owner_before( q1 ) );
BOOST_TEST( q1.owner_before( q4 ) || q4.owner_before( q1 ) );
}
return boost::report_errors();
}

View File

@ -0,0 +1,113 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
{
boost::shared_ptr<int> p1( new int );
boost::shared_ptr<int> p2( p1 );
BOOST_TEST( p1.owner_equals( p2 ) );
BOOST_TEST( p2.owner_equals( p1 ) );
boost::shared_ptr<int> p3( new int );
BOOST_TEST( !p1.owner_equals( p3 ) );
BOOST_TEST( !p3.owner_equals( p1 ) );
boost::shared_ptr<int> p4;
boost::shared_ptr<int> p5;
BOOST_TEST( p4.owner_equals( p5 ) );
BOOST_TEST( p5.owner_equals( p4 ) );
BOOST_TEST( !p4.owner_equals( p3 ) );
BOOST_TEST( !p3.owner_equals( p4 ) );
boost::shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST( !p4.owner_equals( p6 ) );
BOOST_TEST( !p6.owner_equals( p4 ) );
boost::shared_ptr<void> p7( p1 );
BOOST_TEST( p1.owner_equals( p7 ) );
BOOST_TEST( p7.owner_equals( p1 ) );
boost::shared_ptr<void> p8;
BOOST_TEST( !p1.owner_equals( p8 ) );
BOOST_TEST( !p8.owner_equals( p1 ) );
BOOST_TEST( p4.owner_equals( p8 ) );
BOOST_TEST( p8.owner_equals( p4 ) );
boost::weak_ptr<int> q1( p1 );
BOOST_TEST( p1.owner_equals( q1 ) );
BOOST_TEST( q1.owner_equals( p1 ) );
boost::weak_ptr<int> q2( p1 );
BOOST_TEST( q1.owner_equals( q2 ) );
BOOST_TEST( q2.owner_equals( q1 ) );
boost::weak_ptr<int> q3( p3 );
BOOST_TEST( !p1.owner_equals( q3 ) );
BOOST_TEST( !q3.owner_equals( p1 ) );
BOOST_TEST( !q1.owner_equals( q3 ) );
BOOST_TEST( !q3.owner_equals( q1 ) );
boost::weak_ptr<int> q4;
BOOST_TEST( p4.owner_equals( q4 ) );
BOOST_TEST( q4.owner_equals( p4 ) );
BOOST_TEST( !q1.owner_equals( q4 ) );
BOOST_TEST( !q4.owner_equals( q1 ) );
boost::weak_ptr<void> q5;
BOOST_TEST( q4.owner_equals( q5 ) );
BOOST_TEST( q5.owner_equals( q4 ) );
boost::weak_ptr<void> q7( p7 );
BOOST_TEST( p1.owner_equals( q7 ) );
BOOST_TEST( q7.owner_equals( p1 ) );
BOOST_TEST( q1.owner_equals( q7 ) );
BOOST_TEST( q7.owner_equals( q1 ) );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST( q1.owner_equals( q2 ) );
BOOST_TEST( q2.owner_equals( q1 ) );
BOOST_TEST( q1.owner_equals( q7 ) );
BOOST_TEST( q7.owner_equals( q1 ) );
BOOST_TEST( !q1.owner_equals( q3 ) );
BOOST_TEST( !q3.owner_equals( q1 ) );
BOOST_TEST( !q1.owner_equals( q4 ) );
BOOST_TEST( !q4.owner_equals( q1 ) );
}
return boost::report_errors();
}

View File

@ -0,0 +1,85 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
{
boost::shared_ptr<int> p1( new int );
boost::shared_ptr<int> p2( p1 );
BOOST_TEST_EQ( p1.owner_hash_value(), p2.owner_hash_value() );
boost::shared_ptr<int> p3( new int );
BOOST_TEST_NE( p1.owner_hash_value(), p3.owner_hash_value() );
boost::shared_ptr<int> p4;
boost::shared_ptr<int> p5;
BOOST_TEST_EQ( p4.owner_hash_value(), p5.owner_hash_value() );
BOOST_TEST_NE( p4.owner_hash_value(), p3.owner_hash_value() );
boost::shared_ptr<int> p6( static_cast<int*>(0) );
BOOST_TEST_NE( p4.owner_hash_value(), p6.owner_hash_value() );
boost::shared_ptr<void> p7( p1 );
BOOST_TEST_EQ( p1.owner_hash_value(), p7.owner_hash_value() );
boost::shared_ptr<void> p8;
BOOST_TEST_NE( p1.owner_hash_value(), p8.owner_hash_value() );
BOOST_TEST_EQ( p4.owner_hash_value(), p8.owner_hash_value() );
boost::weak_ptr<int> q1( p1 );
BOOST_TEST_EQ( p1.owner_hash_value(), q1.owner_hash_value() );
boost::weak_ptr<int> q2( p1 );
BOOST_TEST_EQ( q1.owner_hash_value(), q2.owner_hash_value() );
boost::weak_ptr<int> q3( p3 );
BOOST_TEST_NE( p1.owner_hash_value(), q3.owner_hash_value() );
BOOST_TEST_NE( q1.owner_hash_value(), q3.owner_hash_value() );
boost::weak_ptr<int> q4;
BOOST_TEST_EQ( p4.owner_hash_value(), q4.owner_hash_value() );
BOOST_TEST_NE( q1.owner_hash_value(), q4.owner_hash_value() );
boost::weak_ptr<void> q5;
BOOST_TEST_EQ( q4.owner_hash_value(), q5.owner_hash_value() );
boost::weak_ptr<void> q7( p7 );
BOOST_TEST_EQ( p1.owner_hash_value(), q7.owner_hash_value() );
BOOST_TEST_EQ( q1.owner_hash_value(), q7.owner_hash_value() );
p1.reset();
p2.reset();
p3.reset();
p7.reset();
BOOST_TEST( q1.expired() );
BOOST_TEST( q2.expired() );
BOOST_TEST( q3.expired() );
BOOST_TEST( q7.expired() );
BOOST_TEST_EQ( q1.owner_hash_value(), q2.owner_hash_value() );
BOOST_TEST_EQ( q1.owner_hash_value(), q7.owner_hash_value() );
BOOST_TEST_NE( q1.owner_hash_value(), q3.owner_hash_value() );
BOOST_TEST_NE( q1.owner_hash_value(), q4.owner_hash_value() );
}
return boost::report_errors();
}

21
test/sp_pedantic_test.cpp Normal file
View File

@ -0,0 +1,21 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
int main()
{
boost::shared_ptr<int> p1( new int );
boost::shared_ptr<int[]> p2( new int[1] );
boost::make_shared<int>();
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1500)
boost::make_shared<int[]>( 1 );
#endif
}

View File

@ -0,0 +1,12 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#define BOOST_SP_REPORT_IMPLEMENTATION
#include <boost/shared_ptr.hpp>
#include <boost/smart_ptr/detail/spinlock.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
int main()
{
}

View File

@ -0,0 +1,51 @@
// Copyright 2011, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/shared_ptr.hpp>
#include <boost/smart_ptr/owner_hash.hpp>
#include <boost/smart_ptr/owner_equal_to.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
int main() {}
#else
#include <unordered_set>
int main()
{
std::unordered_set< boost::shared_ptr<void>, boost::owner_hash< boost::shared_ptr<void> >, boost::owner_equal_to< boost::shared_ptr<void> > > set;
boost::shared_ptr<int> p1( (int*)0 );
boost::shared_ptr<int> p2( p1 );
boost::shared_ptr<void> p3( p1 );
set.insert( p1 );
set.insert( p2 );
set.insert( p3 );
BOOST_TEST_EQ( set.size(), 1 );
boost::shared_ptr<int> p4( (int*)0 );
set.insert( p4 );
BOOST_TEST_EQ( set.size(), 2 );
BOOST_TEST_EQ( set.count( p1 ), 1 );
BOOST_TEST_EQ( set.count( p2 ), 1 );
BOOST_TEST_EQ( set.count( p3 ), 1 );
BOOST_TEST_EQ( set.count( p4 ), 1 );
boost::shared_ptr<int> p5( (int*)0 );
BOOST_TEST_EQ( set.count( p5 ), 0 );
return boost::report_errors();
}
#endif // #if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)

42
test/spinlock_mt_test.cpp Normal file
View File

@ -0,0 +1,42 @@
// Copyright 2018, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/smart_ptr/detail/spinlock.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <boost/bind/bind.hpp>
#include <boost/core/lightweight_test.hpp>
static int count = 0;
static boost::detail::spinlock sp = BOOST_DETAIL_SPINLOCK_INIT;
void f( int n )
{
for( int i = 0; i < n; ++i )
{
boost::detail::spinlock::scoped_lock lock( sp );
++count;
}
}
int main()
{
int const N = 100000; // iterations
int const M = 8; // threads
boost::detail::lw_thread_t th[ M ] = {};
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_create( th[ i ], boost::bind( f, N ) );
}
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_join( th[ i ] );
}
BOOST_TEST_EQ( count, N * M );
return boost::report_errors();
}

View File

@ -0,0 +1,41 @@
// Copyright 2018, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <boost/bind/bind.hpp>
#include <boost/core/lightweight_test.hpp>
static int count = 0;
void f( int n )
{
for( int i = 0; i < n; ++i )
{
boost::detail::spinlock_pool<0>::scoped_lock lock( &count );
++count;
}
}
int main()
{
int const N = 100000; // iterations
int const M = 8; // threads
boost::detail::lw_thread_t th[ M ] = {};
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_create( th[ i ], boost::bind( f, N ) );
}
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_join( th[ i ] );
}
BOOST_TEST_EQ( count, N * M );
return boost::report_errors();
}

74
test/weak_ptr_mt_test.cpp Normal file
View File

@ -0,0 +1,74 @@
// Copyright 2018, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <boost/bind/bind.hpp>
#include <boost/core/lightweight_test.hpp>
static boost::shared_ptr<int> sp( new int );
static boost::weak_ptr<int> wp( sp );
void f1( int n )
{
for( int i = 0; i < n; ++i )
{
boost::weak_ptr<int> p1( wp );
BOOST_TEST( !wp.expired() );
BOOST_TEST( wp.lock() != 0 );
}
}
void f2( int n )
{
for( int i = 0; i < n; ++i )
{
boost::weak_ptr<int> p1( wp );
BOOST_TEST( wp.expired() );
BOOST_TEST( wp.lock() == 0 );
}
}
int main()
{
int const N = 100000; // iterations
int const M = 8; // threads
boost::detail::lw_thread_t th[ M ] = {};
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_create( th[ i ], boost::bind( f1, N ) );
}
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_join( th[ i ] );
}
BOOST_TEST_EQ( sp.use_count(), 1 );
BOOST_TEST_EQ( wp.use_count(), 1 );
sp.reset();
BOOST_TEST_EQ( sp.use_count(), 0 );
BOOST_TEST_EQ( wp.use_count(), 0 );
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_create( th[ i ], boost::bind( f2, N ) );
}
for( int i = 0; i < M; ++i )
{
boost::detail::lw_thread_join( th[ i ] );
}
wp.reset();
return boost::report_errors();
}

76
test/wp_hash_test.cpp Normal file
View File

@ -0,0 +1,76 @@
// Copyright 2011, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/functional/hash.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
{
boost::hash< boost::weak_ptr<int> > hasher;
boost::shared_ptr<int> p1, p2( p1 ), p3( new int ), p4( p3 ), p5( new int );
boost::weak_ptr<int> q1( p1 ), q2( p2 ), q3( p3 ), q4( p4 ), q5( p5 );
BOOST_TEST_EQ( hasher( q1 ), hasher( q2 ) );
BOOST_TEST_NE( hasher( q1 ), hasher( q3 ) );
BOOST_TEST_EQ( hasher( q3 ), hasher( q4 ) );
BOOST_TEST_NE( hasher( q3 ), hasher( q5 ) );
p3.reset();
p4.reset();
p5.reset();
BOOST_TEST_EQ( hasher( q1 ), hasher( q2 ) );
BOOST_TEST_NE( hasher( q1 ), hasher( q3 ) );
BOOST_TEST_EQ( hasher( q3 ), hasher( q4 ) );
BOOST_TEST_NE( hasher( q3 ), hasher( q5 ) );
}
{
boost::hash< boost::weak_ptr<int[]> > hasher;
boost::shared_ptr<int[]> p1, p2( p1 ), p3( new int[1] ), p4( p3 ), p5( new int[1] );
boost::weak_ptr<int[]> q1( p1 ), q2( p2 ), q3( p3 ), q4( p4 ), q5( p5 );
BOOST_TEST_EQ( hasher( q1 ), hasher( q2 ) );
BOOST_TEST_NE( hasher( q1 ), hasher( q3 ) );
BOOST_TEST_EQ( hasher( q3 ), hasher( q4 ) );
BOOST_TEST_NE( hasher( q3 ), hasher( q5 ) );
p3.reset();
p4.reset();
p5.reset();
BOOST_TEST_EQ( hasher( q1 ), hasher( q2 ) );
BOOST_TEST_NE( hasher( q1 ), hasher( q3 ) );
BOOST_TEST_EQ( hasher( q3 ), hasher( q4 ) );
BOOST_TEST_NE( hasher( q3 ), hasher( q5 ) );
}
{
boost::hash< boost::weak_ptr<int[1]> > hasher;
boost::shared_ptr<int[1]> p1, p2( p1 ), p3( new int[1] ), p4( p3 ), p5( new int[1] );
boost::weak_ptr<int[1]> q1( p1 ), q2( p2 ), q3( p3 ), q4( p4 ), q5( p5 );
BOOST_TEST_EQ( hasher( q1 ), hasher( q2 ) );
BOOST_TEST_NE( hasher( q1 ), hasher( q3 ) );
BOOST_TEST_EQ( hasher( q3 ), hasher( q4 ) );
BOOST_TEST_NE( hasher( q3 ), hasher( q5 ) );
p3.reset();
p4.reset();
p5.reset();
BOOST_TEST_EQ( hasher( q1 ), hasher( q2 ) );
BOOST_TEST_NE( hasher( q1 ), hasher( q3 ) );
BOOST_TEST_EQ( hasher( q3 ), hasher( q4 ) );
BOOST_TEST_NE( hasher( q3 ), hasher( q5 ) );
}
return boost::report_errors();
}

61
test/wp_hash_test2.cpp Normal file
View File

@ -0,0 +1,61 @@
// Copyright 2011, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <functional>
#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
int main() {}
#else
int main()
{
{
boost::shared_ptr<int> p1, p2( new int );
boost::weak_ptr<int> q1( p1 ), q2( p2 ), q3;
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int> >()( q1 ), q1.owner_hash_value() );
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int> >()( q2 ), q2.owner_hash_value() );
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int> >()( q3 ), q3.owner_hash_value() );
p2.reset();
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int> >()( q2 ), q2.owner_hash_value() );
}
{
boost::shared_ptr<int[]> p1, p2( new int[1] );
boost::weak_ptr<int[]> q1( p1 ), q2( p2 ), q3;
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int[]> >()( q1 ), q1.owner_hash_value() );
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int[]> >()( q2 ), q2.owner_hash_value() );
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int[]> >()( q3 ), q3.owner_hash_value() );
p2.reset();
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int[]> >()( q2 ), q2.owner_hash_value() );
}
{
boost::shared_ptr<int[1]> p1, p2( new int[1] );
boost::weak_ptr<int[1]> q1( p1 ), q2( p2 ), q3;
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int[1]> >()( q1 ), q1.owner_hash_value() );
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int[1]> >()( q2 ), q2.owner_hash_value() );
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int[1]> >()( q3 ), q3.owner_hash_value() );
p2.reset();
BOOST_TEST_EQ( std::hash< boost::weak_ptr<int[1]> >()( q2 ), q2.owner_hash_value() );
}
return boost::report_errors();
}
#endif // #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)

View File

@ -0,0 +1,87 @@
// Copyright 2011, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
int main() {}
#else
#include <unordered_set>
int main()
{
std::unordered_set< boost::weak_ptr<void> > set;
boost::shared_ptr<int> p1( (int*)0 );
boost::shared_ptr<int> p2( p1 );
boost::shared_ptr<void> p3( p1 );
set.insert( p1 );
set.insert( p2 );
set.insert( p3 );
BOOST_TEST_EQ( set.size(), 1 );
boost::weak_ptr<int> q1( p1 );
boost::weak_ptr<int> q2( p2 );
boost::weak_ptr<void> q3( p3 );
boost::weak_ptr<int> q4( q2 );
boost::weak_ptr<void> q5( q3 );
set.insert( q1 );
set.insert( q2 );
set.insert( q3 );
set.insert( q4 );
set.insert( q5 );
BOOST_TEST_EQ( set.size(), 1 );
boost::shared_ptr<int> p6( (int*)0 );
set.insert( p6 );
BOOST_TEST_EQ( set.size(), 2 );
boost::weak_ptr<int> q6( p6 );
set.insert( q6 );
BOOST_TEST_EQ( set.size(), 2 );
BOOST_TEST_EQ( set.count( q1 ), 1 );
BOOST_TEST_EQ( set.count( q2 ), 1 );
BOOST_TEST_EQ( set.count( q3 ), 1 );
BOOST_TEST_EQ( set.count( q4 ), 1 );
BOOST_TEST_EQ( set.count( q5 ), 1 );
BOOST_TEST_EQ( set.count( q6 ), 1 );
boost::shared_ptr<int> p7( (int*)0 );
boost::weak_ptr<int> q7( p7 );
BOOST_TEST_EQ( set.count( q7 ), 0 );
p1.reset();
p2.reset();
p3.reset();
p6.reset();
p7.reset();
BOOST_TEST_EQ( set.count( q1 ), 1 );
BOOST_TEST_EQ( set.count( q2 ), 1 );
BOOST_TEST_EQ( set.count( q3 ), 1 );
BOOST_TEST_EQ( set.count( q4 ), 1 );
BOOST_TEST_EQ( set.count( q5 ), 1 );
BOOST_TEST_EQ( set.count( q6 ), 1 );
BOOST_TEST_EQ( set.count( q7 ), 0 );
return boost::report_errors();
}
#endif // #if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)