forked from boostorg/smart_ptr
Merge branch 'feature/local_shared_ptr' into develop
This commit is contained in:
@ -37,6 +37,8 @@ include::smart_ptr/intrusive_ptr.adoc[]
|
||||
|
||||
include::smart_ptr/intrusive_ref_counter.adoc[]
|
||||
|
||||
include::smart_ptr/local_shared_ptr.adoc[]
|
||||
|
||||
include::smart_ptr/pointer_cast.adoc[]
|
||||
|
||||
include::smart_ptr/pointer_to_other.adoc[]
|
||||
|
@ -24,13 +24,14 @@ deletion of the object when it is no longer needed. As such, they are examples o
|
||||
acquisition is initialization" idiom described in Bjarne Stroustrup's "The C++ Programming Language",
|
||||
3rd edition, Section 14.4, Resource Management.
|
||||
|
||||
This library provides five smart pointer class templates:
|
||||
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;
|
||||
* `<<intrusive_ptr,intrusive_ptr>>`, a pointer to objects with an embedded reference count.
|
||||
* `<<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.
|
||||
|
||||
`shared_ptr` and `weak_ptr` are part of the {cpp} standard since its 2011 iteration.
|
||||
|
||||
|
719
doc/smart_ptr/local_shared_ptr.adoc
Normal file
719
doc/smart_ptr/local_shared_ptr.adoc
Normal file
@ -0,0 +1,719 @@
|
||||
////
|
||||
Copyright 2017 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
|
||||
////
|
||||
|
||||
[#local_shared_ptr]
|
||||
# local_shared_ptr: Shared Ownership within a Single Thread
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix: local_shared_ptr_
|
||||
|
||||
## Description
|
||||
|
||||
`local_shared_ptr` is nearly identical to `shared_ptr`, with the only difference of note being that its reference count is
|
||||
updated with non-atomic operations. As such, a `local_shared_ptr` and all its copies must reside in (be local to) a single
|
||||
thread (hence the name.)
|
||||
|
||||
`local_shared_ptr` can be converted to `shared_ptr` and vice versa. Creating a `local_shared_ptr` from a `shared_ptr` creates
|
||||
a new local reference count; this means that two `local_shared_ptr` instances, both created from the same `shared_ptr`, refer
|
||||
to the same object but don't share the same count, and as such, can safely be used by two different threads.
|
||||
|
||||
.Two local_shared_ptr instances created from a shared_ptr
|
||||
```
|
||||
shared_ptr<X> p1( new X );
|
||||
|
||||
local_shared_ptr<X> p2( p1 ); // p2.local_use_count() == 1
|
||||
local_shared_ptr<X> p3( p1 ); // p3.local_use_count() also 1
|
||||
```
|
||||
|
||||
Creating the second `local_shared_ptr` from the first one, however, does lead to the two sharing the same count:
|
||||
|
||||
.A local_shared_ptr created from another local_shared_ptr
|
||||
```
|
||||
shared_ptr<X> p1( new X );
|
||||
|
||||
local_shared_ptr<X> p2( p1 ); // p2.local_use_count() == 1
|
||||
local_shared_ptr<X> p3( p2 ); // p3.local_use_count() == 2
|
||||
```
|
||||
|
||||
Two `shared_ptr` instances created from the same `local_shared_ptr` do share ownership:
|
||||
|
||||
.Two shared_ptr instances created from a local_shared_ptr
|
||||
```
|
||||
local_shared_ptr<X> p1( new X );
|
||||
|
||||
shared_ptr<X> p2( p1 ); // p2.use_count() == 2
|
||||
shared_ptr<X> p3( p1 ); // p3.use_count() == 3
|
||||
```
|
||||
|
||||
Here `p2.use_count()` is 2, because `p1` holds a reference, too.
|
||||
|
||||
One can think of `local_shared_ptr<T>` as `shared_ptr<shared_ptr<T>>`, with the outer `shared_ptr` using non-atomic operations for
|
||||
its count. Converting from `local_shared_ptr` to `shared_ptr` gives you a copy of the inner `shared_ptr`; converting from `shared_ptr`
|
||||
wraps it into an outer `shared_ptr` with a non-atomic use count (conceptually speaking) and returns the result.
|
||||
|
||||
## Synopsis
|
||||
|
||||
`local_shared_ptr` is defined in `<boost/smart_ptr/local_shared_ptr.hpp>`.
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class T> class local_shared_ptr {
|
||||
public:
|
||||
|
||||
typedef /*see below*/ element_type;
|
||||
|
||||
// constructors
|
||||
|
||||
constexpr local_shared_ptr() noexcept;
|
||||
constexpr local_shared_ptr(std::nullptr_t) noexcept;
|
||||
|
||||
template<class Y> explicit local_shared_ptr(Y * p);
|
||||
|
||||
template<class Y, class D> local_shared_ptr(Y * p, D d);
|
||||
template<class D> local_shared_ptr(std::nullptr_t p, D d);
|
||||
|
||||
template<class Y, class D, class A> local_shared_ptr(Y * p, D d, A a);
|
||||
template<class D, class A> local_shared_ptr(std::nullptr_t p, D d, A a);
|
||||
|
||||
local_shared_ptr(local_shared_ptr const & r) noexcept;
|
||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r) noexcept;
|
||||
|
||||
local_shared_ptr(local_shared_ptr && r) noexcept;
|
||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> && r) noexcept;
|
||||
|
||||
template<class Y> local_shared_ptr( shared_ptr<Y> const & r );
|
||||
template<class Y> local_shared_ptr( shared_ptr<Y> && r );
|
||||
|
||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r, element_type * p) noexcept;
|
||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> && r, element_type * p) noexcept;
|
||||
|
||||
template<class Y, class D> local_shared_ptr(std::unique_ptr<Y, D> && r);
|
||||
|
||||
// destructor
|
||||
|
||||
~local_shared_ptr() noexcept;
|
||||
|
||||
// assignment
|
||||
|
||||
local_shared_ptr & operator=(local_shared_ptr const & r) noexcept;
|
||||
template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const & r) noexcept;
|
||||
|
||||
local_shared_ptr & operator=(local_shared_ptr const && r) noexcept;
|
||||
template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const && r) noexcept;
|
||||
|
||||
template<class Y, class D> local_shared_ptr & operator=(std::unique_ptr<Y, D> && r);
|
||||
|
||||
local_shared_ptr & operator=(std::nullptr_t) noexcept;
|
||||
|
||||
// reset
|
||||
|
||||
void reset() noexcept;
|
||||
|
||||
template<class Y> void reset(Y * p);
|
||||
template<class Y, class D> void reset(Y * p, D d);
|
||||
template<class Y, class D, class A> void reset(Y * p, D d, A a);
|
||||
|
||||
template<class Y> void reset(local_shared_ptr<Y> const & r, element_type * p) noexcept;
|
||||
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
|
||||
|
||||
// only valid when T is an array type
|
||||
element_type & operator[](std::ptrdiff_t i) const noexcept;
|
||||
|
||||
element_type * get() const noexcept;
|
||||
|
||||
long local_use_count() const noexcept;
|
||||
|
||||
// conversions
|
||||
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
template<class Y> operator shared_ptr<Y>() const noexcept;
|
||||
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;
|
||||
};
|
||||
|
||||
// comparisons
|
||||
|
||||
template<class T, class U>
|
||||
bool operator==(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
template<class T, class U>
|
||||
bool operator==(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
|
||||
template<class T, class U>
|
||||
bool operator==(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
|
||||
template<class T, class U>
|
||||
bool operator!=(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
template<class T, class U>
|
||||
bool operator!=(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
|
||||
template<class T, class U>
|
||||
bool operator!=(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
|
||||
template<class T> bool operator==(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
|
||||
template<class T> bool operator==(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
|
||||
|
||||
template<class T> bool operator!=(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
|
||||
template<class T> bool operator!=(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
|
||||
|
||||
template<class T, class U>
|
||||
bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
|
||||
// swap
|
||||
|
||||
template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) noexcept;
|
||||
|
||||
// get_pointer
|
||||
|
||||
template<class T>
|
||||
typename local_shared_ptr<T>::element_type *
|
||||
get_pointer(local_shared_ptr<T> const & p) noexcept;
|
||||
|
||||
// casts
|
||||
|
||||
template<class T, class U>
|
||||
local_shared_ptr<T> static_pointer_cast(local_shared_ptr<U> const & r) noexcept;
|
||||
|
||||
template<class T, class U>
|
||||
local_shared_ptr<T> const_pointer_cast(local_shared_ptr<U> const & r) noexcept;
|
||||
|
||||
template<class T, class U>
|
||||
local_shared_ptr<T> dynamic_pointer_cast(local_shared_ptr<U> const & r) noexcept;
|
||||
|
||||
template<class T, class U>
|
||||
local_shared_ptr<T> reinterpret_pointer_cast(local_shared_ptr<U> const & r) noexcept;
|
||||
|
||||
// stream I/O
|
||||
|
||||
template<class E, class T, class Y>
|
||||
std::basic_ostream<E, T> &
|
||||
operator<< (std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p);
|
||||
|
||||
// get_deleter
|
||||
|
||||
template<class D, class T> D * get_deleter(local_shared_ptr<T> const & p) noexcept;
|
||||
}
|
||||
```
|
||||
|
||||
## Members
|
||||
|
||||
### element_type
|
||||
```
|
||||
typedef ... element_type;
|
||||
```
|
||||
`element_type` is `T` when `T` is not an array type, and `U` when `T` is `U[]` or `U[N]`.
|
||||
|
||||
### default constructor
|
||||
```
|
||||
constexpr local_shared_ptr() noexcept;
|
||||
```
|
||||
```
|
||||
constexpr local_shared_ptr(std::nullptr_t) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Constructs an empty `local_shared_ptr`.
|
||||
Postconditions:: `local_use_count() == 0 && get() == 0`.
|
||||
|
||||
### pointer constructor
|
||||
```
|
||||
template<class Y> explicit local_shared_ptr(Y * p);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p )`.
|
||||
|
||||
Postconditions:: `local_use_count() == 1 && get() == p`.
|
||||
|
||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
|
||||
|
||||
### constructors taking a deleter
|
||||
```
|
||||
template<class Y, class D> local_shared_ptr(Y * p, D d);
|
||||
```
|
||||
```
|
||||
template<class D> local_shared_ptr(std::nullptr_t p, D d);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p, d )`.
|
||||
|
||||
Postconditions:: `local_use_count() == 1 && get() == p`.
|
||||
|
||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
|
||||
|
||||
```
|
||||
template<class Y, class D, class A> local_shared_ptr(Y * p, D d, A a);
|
||||
```
|
||||
```
|
||||
template<class D, class A> local_shared_ptr(std::nullptr_t p, D d, A a);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Constructs a `local_shared_ptr` that owns `shared_ptr<T>( p, d, a )`.
|
||||
|
||||
Postconditions:: `local_use_count() == 1 && get() == p`.
|
||||
|
||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
|
||||
|
||||
### copy and converting constructors
|
||||
```
|
||||
local_shared_ptr(local_shared_ptr const & r) noexcept;
|
||||
```
|
||||
```
|
||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `Y*` should be convertible to `T*`.
|
||||
|
||||
Effects:: If `r` is empty, constructs an empty `local_shared_ptr`; otherwise, constructs a `local_shared_ptr` that shares ownership with `r`.
|
||||
|
||||
Postconditions:: `get() == r.get() && local_use_count() == r.local_use_count()`.
|
||||
|
||||
### move constructors
|
||||
```
|
||||
local_shared_ptr(local_shared_ptr && r) noexcept;
|
||||
```
|
||||
```
|
||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> && r) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `Y*` should be convertible to `T*`.
|
||||
|
||||
Effects:: Move-constructs a `local_shared_ptr` from `r`.
|
||||
|
||||
Postconditions:: `*this` contains the old value of `r`. `r` is empty and `r.get() == 0`.
|
||||
|
||||
### shared_ptr constructor
|
||||
```
|
||||
template<class Y> local_shared_ptr( shared_ptr<Y> const & r );
|
||||
```
|
||||
```
|
||||
template<class Y> local_shared_ptr( shared_ptr<Y> && r );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Constructs a `local_shared_ptr` that owns `r`.
|
||||
|
||||
Postconditions:: `local_use_count() == 1`. `get()` returns the old value of `r.get()`.
|
||||
|
||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
|
||||
|
||||
### aliasing constructor
|
||||
```
|
||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r, element_type * p) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: constructs a `local_shared_ptr` that shares ownership with `r` and stores `p`.
|
||||
|
||||
Postconditions:: `get() == p && local_use_count() == r.local_use_count()`.
|
||||
|
||||
### aliasing move constructor
|
||||
```
|
||||
template<class Y> local_shared_ptr(local_shared_ptr<Y> && r, element_type * p) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Move-constructs a `local_shared_ptr` from `r`, while storing `p` instead.
|
||||
|
||||
Postconditions:: `get() == p` and `local_use_count()` equals the old count of `r`. `r` is empty and `r.get() == 0`.
|
||||
|
||||
### unique_ptr constructor
|
||||
```
|
||||
template<class Y, class D> local_shared_ptr(std::unique_ptr<Y, D> && r);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `Y*` should be convertible to `T*`.
|
||||
|
||||
Effects::
|
||||
- When `r.get() == 0`, equivalent to `local_shared_ptr()`;
|
||||
- Otherwise, constructs a `local_shared_ptr` that owns `shared_ptr<T>( std::move(r) )`.
|
||||
|
||||
Throws:: `std::bad_alloc`, or an implementation-defined exception when a resource other than memory could not be obtained.
|
||||
|
||||
Exception safety:: If an exception is thrown, the constructor has no effect.
|
||||
|
||||
### destructor
|
||||
```
|
||||
~local_shared_ptr() noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects::
|
||||
- If `*this` is empty, or shares ownership with another `local_shared_ptr` instance (`local_use_count() > 1`), there are no side effects.
|
||||
- Otherwise, destroys the owned `shared_ptr`.
|
||||
|
||||
### assignment
|
||||
```
|
||||
local_shared_ptr & operator=(local_shared_ptr const & r) noexcept;
|
||||
```
|
||||
```
|
||||
template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const & r) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr(r).swap(*this)`.
|
||||
Returns:: `*this`.
|
||||
|
||||
```
|
||||
local_shared_ptr & operator=(local_shared_ptr && r) noexcept;
|
||||
```
|
||||
```
|
||||
template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> && r) noexcept;
|
||||
```
|
||||
```
|
||||
template<class Y, class D> local_shared_ptr & operator=(std::unique_ptr<Y, D> && r);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr(std::move(r)).swap(*this)`.
|
||||
Returns:: `*this`.
|
||||
|
||||
```
|
||||
local_shared_ptr & operator=(std::nullptr_t) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr().swap(*this)`.
|
||||
Returns:: `*this`.
|
||||
|
||||
### reset
|
||||
```
|
||||
void reset() noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr().swap(*this)`.
|
||||
|
||||
```
|
||||
template<class Y> void reset(Y * p);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr(p).swap(*this)`.
|
||||
|
||||
```
|
||||
template<class Y, class D> void reset(Y * p, D d);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr(p, d).swap(*this)`.
|
||||
|
||||
```
|
||||
template<class Y, class D, class A> void reset(Y * p, D d, A a);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr(p, d, a).swap(*this)`.
|
||||
|
||||
```
|
||||
template<class Y> void reset(local_shared_ptr<Y> const & r, element_type * p) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr(r, p).swap(*this)`.
|
||||
|
||||
```
|
||||
template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`.
|
||||
|
||||
### indirection
|
||||
```
|
||||
T & operator*() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `T` should not be an array type.
|
||||
Returns:: `*get()`.
|
||||
|
||||
```
|
||||
T * operator->() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `T` should not be an array type.
|
||||
Returns:: `get()`.
|
||||
|
||||
```
|
||||
element_type & operator[](std::ptrdiff_t i) const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `T` should be an array type. The stored pointer must not be 0. `i >= 0`. If `T` is `U[N]`, `i < N`.
|
||||
Returns:: `get()[i]`.
|
||||
|
||||
### get
|
||||
|
||||
```
|
||||
element_type * get() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: The stored pointer.
|
||||
|
||||
### local_use_count
|
||||
```
|
||||
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.
|
||||
|
||||
### conversions
|
||||
```
|
||||
explicit operator bool() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `get() != 0`.
|
||||
|
||||
NOTE: On C++03 compilers, the return value is of an unspecified type.
|
||||
|
||||
```
|
||||
template<class Y> operator shared_ptr<Y>() const noexcept;
|
||||
```
|
||||
```
|
||||
template<class Y> operator weak_ptr<Y>() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `T*` should be convertible to `Y*`.
|
||||
Returns:: a copy of the owned `shared_ptr`.
|
||||
|
||||
### swap
|
||||
```
|
||||
void swap(local_shared_ptr & b) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
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;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: See the description of `operator<`.
|
||||
|
||||
## Free Functions
|
||||
|
||||
### comparison
|
||||
```
|
||||
template<class T, class U>
|
||||
bool operator==(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
```
|
||||
```
|
||||
template<class T, class U>
|
||||
bool operator==(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
|
||||
```
|
||||
```
|
||||
template<class T, class U>
|
||||
bool operator==(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `a.get() == b.get()`.
|
||||
|
||||
```
|
||||
template<class T, class U>
|
||||
bool operator!=(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
```
|
||||
```
|
||||
template<class T, class U>
|
||||
bool operator!=(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
|
||||
```
|
||||
```
|
||||
template<class T, class U>
|
||||
bool operator!=(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `a.get() != b.get()`.
|
||||
|
||||
```
|
||||
template<class T> bool operator==(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
|
||||
```
|
||||
```
|
||||
template<class T> bool operator==(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `p.get() == 0`.
|
||||
|
||||
```
|
||||
template<class T> bool operator!=(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
|
||||
```
|
||||
```
|
||||
template<class T> bool operator!=(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `p.get() != 0`.
|
||||
|
||||
```
|
||||
template<class T, class U>
|
||||
bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: An unspecified value such that
|
||||
- `operator<` is a strict weak ordering as described in section [lib.alg.sorting] of the {cpp} standard;
|
||||
- under the equivalence relation defined by `operator<`, `!(a < b) && !(b < a)`, two `local_shared_ptr` instances
|
||||
are equivalent if and only if they share ownership or are both empty.
|
||||
|
||||
NOTE: Allows `local_shared_ptr` objects to be used as keys in associative containers.
|
||||
|
||||
NOTE: The rest of the comparison operators are omitted by design.
|
||||
|
||||
### swap
|
||||
```
|
||||
template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Equivalent to `a.swap(b)`.
|
||||
|
||||
### get_pointer
|
||||
```
|
||||
template<class T>
|
||||
typename local_shared_ptr<T>::element_type *
|
||||
get_pointer(local_shared_ptr<T> const & p) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `p.get()`.
|
||||
|
||||
NOTE: Provided as an aid to generic programming. Used by `mem_fn`.
|
||||
|
||||
### static_pointer_cast
|
||||
```
|
||||
template<class T, class U>
|
||||
local_shared_ptr<T> static_pointer_cast(local_shared_ptr<U> const & r) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: The expression `static_cast<T*>( (U*)0 )` must be well-formed.
|
||||
Returns:: `local_shared_ptr<T>( r, static_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.
|
||||
|
||||
CAUTION: The seemingly equivalent expression `local_shared_ptr<T>(static_cast<T*>(r.get()))` will eventually
|
||||
result in undefined behavior, attempting to delete the same object twice.
|
||||
|
||||
### const_pointer_cast
|
||||
```
|
||||
template<class T, class U>
|
||||
local_shared_ptr<T> const_pointer_cast(local_shared_ptr<U> const & r) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: The expression `const_cast<T*>( (U*)0 )` must be well-formed.
|
||||
Returns:: `local_shared_ptr<T>( r, const_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.
|
||||
|
||||
### dynamic_pointer_cast
|
||||
```
|
||||
template<class T, class U>
|
||||
local_shared_ptr<T> dynamic_pointer_cast(local_shared_ptr<U> const & r) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: The expression `dynamic_cast<T*>( (U*)0 )` must be well-formed.
|
||||
Returns::
|
||||
- When `dynamic_cast<typename local_shared_ptr<T>::element_type*>(r.get())` returns a nonzero value `p`, `local_shared_ptr<T>(r, p)`;
|
||||
- Otherwise, `local_shared_ptr<T>()`.
|
||||
|
||||
### reinterpret_pointer_cast
|
||||
```
|
||||
template<class T, class U>
|
||||
local_shared_ptr<T> reinterpret_pointer_cast(local_shared_ptr<U> const & r) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: The expression `reinterpret_cast<T*>( (U*)0 )` must be well-formed.
|
||||
Returns:: `local_shared_ptr<T>( r, reinterpret_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )`.
|
||||
|
||||
### operator<<
|
||||
```
|
||||
template<class E, class T, class Y>
|
||||
std::basic_ostream<E, T> &
|
||||
operator<< (std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: `os << p.get();`.
|
||||
Returns:: `os`.
|
||||
|
||||
### get_deleter
|
||||
```
|
||||
template<class D, class T>
|
||||
D * get_deleter(local_shared_ptr<T> const & p) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: If `*this` owns a `shared_ptr` instance `p`, `get_deleter<D>( p )`, otherwise 0.
|
||||
|
@ -767,6 +767,10 @@ public:
|
||||
&reinterpret_cast<char&>(deleter_) : 0;
|
||||
}
|
||||
|
||||
void* get_local_deleter(const sp_typeinfo&) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* get_untyped_deleter() {
|
||||
return &reinterpret_cast<char&>(deleter_);
|
||||
}
|
||||
@ -809,6 +813,10 @@ public:
|
||||
&reinterpret_cast<char&>(deleter_) : 0;
|
||||
}
|
||||
|
||||
void* get_local_deleter(const sp_typeinfo&) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* get_untyped_deleter() {
|
||||
return &reinterpret_cast<char&>(deleter_);
|
||||
}
|
||||
@ -856,6 +864,10 @@ public:
|
||||
&reinterpret_cast<char&>(deleter_) : 0;
|
||||
}
|
||||
|
||||
void* get_local_deleter(const sp_typeinfo&) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* get_untyped_deleter() {
|
||||
return &reinterpret_cast<char&>(deleter_);
|
||||
}
|
||||
@ -902,6 +914,10 @@ public:
|
||||
&reinterpret_cast<char&>(deleter_) : 0;
|
||||
}
|
||||
|
||||
void* get_local_deleter(const sp_typeinfo&) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* get_untyped_deleter() {
|
||||
return &reinterpret_cast<char&>(deleter_);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/ for documentation.
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/shared_count.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <utility>
|
||||
#include <climits>
|
||||
@ -55,9 +55,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual void destroy() BOOST_SP_NOEXCEPT = 0;
|
||||
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0;
|
||||
|
||||
virtual boost::shared_ptr<void> get_shared_ptr() const BOOST_SP_NOEXCEPT = 0;
|
||||
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT = 0;
|
||||
|
||||
void add_ref() BOOST_SP_NOEXCEPT
|
||||
{
|
||||
@ -78,7 +78,7 @@ public:
|
||||
|
||||
if( local_use_count_ == 0 )
|
||||
{
|
||||
destroy();
|
||||
local_cb_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,30 +96,30 @@ private:
|
||||
|
||||
private:
|
||||
|
||||
boost::shared_ptr<void const volatile> pn_;
|
||||
shared_count pn_;
|
||||
|
||||
public:
|
||||
|
||||
template<class T> explicit local_counted_impl( boost::shared_ptr<T> const& pn ): pn_( pn )
|
||||
explicit local_counted_impl( shared_count const& pn ): pn_( pn )
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
template<class T> explicit local_counted_impl( boost::shared_ptr<T>&& pn ): pn_( std::move(pn) )
|
||||
explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
virtual void destroy() BOOST_SP_NOEXCEPT
|
||||
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual boost::shared_ptr<void> get_shared_ptr() const BOOST_SP_NOEXCEPT
|
||||
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return const_pointer_cast<void>( pn_ );
|
||||
return pn_;
|
||||
}
|
||||
};
|
||||
|
||||
@ -127,16 +127,16 @@ class local_counted_impl_em: public local_counted_base
|
||||
{
|
||||
public:
|
||||
|
||||
boost::shared_ptr<void const volatile> pn_;
|
||||
shared_count pn_;
|
||||
|
||||
virtual void destroy() BOOST_SP_NOEXCEPT
|
||||
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
|
||||
{
|
||||
pn_.reset();
|
||||
shared_count().swap( pn_ );
|
||||
}
|
||||
|
||||
virtual boost::shared_ptr<void> get_shared_ptr() const BOOST_SP_NOEXCEPT
|
||||
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return const_pointer_cast<void>( pn_ );
|
||||
return pn_;
|
||||
}
|
||||
};
|
||||
|
||||
|
91
include/boost/smart_ptr/detail/local_sp_deleter.hpp
Normal file
91
include/boost/smart_ptr/detail/local_sp_deleter.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/local_sp_deleter.hpp
|
||||
//
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/ for documentation.
|
||||
|
||||
#include <boost/smart_ptr/detail/local_counted_base.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class D> class local_sp_deleter: public local_counted_impl_em
|
||||
{
|
||||
private:
|
||||
|
||||
D d_;
|
||||
|
||||
public:
|
||||
|
||||
local_sp_deleter(): d_()
|
||||
{
|
||||
}
|
||||
|
||||
explicit local_sp_deleter( D const& d ) BOOST_SP_NOEXCEPT: d_( d )
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
D& deleter()
|
||||
{
|
||||
return d_;
|
||||
}
|
||||
|
||||
template<class Y> void operator()( Y* p ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
d_( p );
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
void operator()( boost::detail::sp_nullptr_t p ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
d_( p );
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template<> class local_sp_deleter<void>
|
||||
{
|
||||
};
|
||||
|
||||
template<class D> D * get_local_deleter( local_sp_deleter<D> * p )
|
||||
{
|
||||
return &p->deleter();
|
||||
}
|
||||
|
||||
inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED
|
@ -496,6 +496,11 @@ public:
|
||||
return pi_? pi_->get_deleter( ti ): 0;
|
||||
}
|
||||
|
||||
void * get_local_deleter( sp_typeinfo const & ti ) const
|
||||
{
|
||||
return pi_? pi_->get_local_deleter( ti ): 0;
|
||||
}
|
||||
|
||||
void * get_untyped_deleter() const
|
||||
{
|
||||
return pi_? pi_->get_untyped_deleter(): 0;
|
||||
|
@ -104,6 +104,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -124,6 +124,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -111,6 +111,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -135,6 +135,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -135,6 +135,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -120,6 +120,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -127,6 +127,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -115,6 +115,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -62,6 +62,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -90,6 +90,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -109,6 +109,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -104,6 +104,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
|
||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||
#include <boost/smart_ptr/detail/quick_allocator.hpp>
|
||||
@ -50,6 +51,19 @@ void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// get_local_deleter
|
||||
|
||||
template<class D> class local_sp_deleter;
|
||||
|
||||
template<class D> D * get_local_deleter( D * /*p*/ )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class D> D * get_local_deleter( local_sp_deleter<D> * p );
|
||||
|
||||
//
|
||||
|
||||
template<class X> class sp_counted_impl_p: public sp_counted_base
|
||||
{
|
||||
private:
|
||||
@ -83,6 +97,11 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void * get_local_deleter( sp_typeinfo const & )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return 0;
|
||||
@ -158,6 +177,11 @@ public:
|
||||
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return &reinterpret_cast<char&>( del );
|
||||
@ -246,6 +270,11 @@ public:
|
||||
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_local_deleter( sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return &reinterpret_cast<char&>( d_ );
|
||||
|
@ -11,7 +11,6 @@
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/ for documentation.
|
||||
|
||||
#include <boost/smart_ptr/detail/local_counted_base.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
|
||||
namespace boost
|
||||
@ -22,46 +21,7 @@ template<class T> class local_shared_ptr;
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class D> class local_sp_deleter: public local_counted_impl_em
|
||||
{
|
||||
private:
|
||||
|
||||
D d_;
|
||||
|
||||
public:
|
||||
|
||||
local_sp_deleter(): d_()
|
||||
{
|
||||
}
|
||||
|
||||
explicit local_sp_deleter( D const& d ) BOOST_SP_NOEXCEPT: d_( d )
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y> void operator()( Y* p ) const BOOST_SP_NOEXCEPT
|
||||
{
|
||||
d_( p );
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
void operator()( boost::detail::sp_nullptr_t p ) const BOOST_SP_NOEXCEPT
|
||||
{
|
||||
d_( p );
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E > * ppx, Y * p, boost::detail::local_counted_base * & pn )
|
||||
template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, E >();
|
||||
|
||||
@ -71,12 +31,12 @@ template< class E, class Y > inline void lsp_pointer_construct( boost::local_sha
|
||||
|
||||
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
|
||||
|
||||
pd->pn_ = p2;
|
||||
pd->pn_ = p2._internal_count();
|
||||
|
||||
pn = pd;
|
||||
}
|
||||
|
||||
template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[] > * ppx, Y * p, boost::detail::local_counted_base * & pn )
|
||||
template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], E[] >();
|
||||
|
||||
@ -86,12 +46,12 @@ template< class E, class Y > inline void lsp_pointer_construct( boost::local_sha
|
||||
|
||||
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
|
||||
|
||||
pd->pn_ = p2;
|
||||
pd->pn_ = p2._internal_count();
|
||||
|
||||
pn = pd;
|
||||
}
|
||||
|
||||
template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[N] > * ppx, Y * p, boost::detail::local_counted_base * & pn )
|
||||
template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[N] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[N], E[N] >();
|
||||
|
||||
@ -101,12 +61,12 @@ template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( b
|
||||
|
||||
D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
|
||||
|
||||
pd->pn_ = p2;
|
||||
pd->pn_ = p2._internal_count();
|
||||
|
||||
pn = pd;
|
||||
}
|
||||
|
||||
template< class E, class P, class D > inline void lsp_deleter_construct( boost::local_shared_ptr< E > * ppx, P p, D const& d, boost::detail::local_counted_base * & pn )
|
||||
template< class E, class P, class D > inline void lsp_deleter_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, boost::detail::local_counted_base * & pn )
|
||||
{
|
||||
typedef boost::detail::local_sp_deleter<D> D2;
|
||||
|
||||
@ -114,12 +74,12 @@ template< class E, class P, class D > inline void lsp_deleter_construct( boost::
|
||||
|
||||
D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
|
||||
|
||||
pd->pn_ = p2;
|
||||
pd->pn_ = p2._internal_count();
|
||||
|
||||
pn = pd;
|
||||
}
|
||||
|
||||
template< class E, class P, class D, class A > inline void lsp_allocator_construct( boost::local_shared_ptr< E > * ppx, P p, D const& d, A const& a, boost::detail::local_counted_base * & pn )
|
||||
template< class E, class P, class D, class A > inline void lsp_allocator_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, A const& a, boost::detail::local_counted_base * & pn )
|
||||
{
|
||||
typedef boost::detail::local_sp_deleter<D> D2;
|
||||
|
||||
@ -127,11 +87,15 @@ template< class E, class P, class D, class A > inline void lsp_allocator_constru
|
||||
|
||||
D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
|
||||
|
||||
pd->pn_ = p2;
|
||||
pd->pn_ = p2._internal_count();
|
||||
|
||||
pn = pd;
|
||||
}
|
||||
|
||||
struct lsp_internal_constructor_tag
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
@ -184,6 +148,11 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
// internal constructor, used by make_shared
|
||||
BOOST_CONSTEXPR local_shared_ptr( boost::detail::lsp_internal_constructor_tag, T * px_, boost::detail::local_counted_base * pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ )
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
explicit local_shared_ptr( Y * p ): px( p ), pn( 0 )
|
||||
{
|
||||
@ -228,7 +197,7 @@ public:
|
||||
|
||||
if( r.use_count() != 0 )
|
||||
{
|
||||
pn = new boost::detail::local_counted_impl( r );
|
||||
pn = new boost::detail::local_counted_impl( r._internal_count() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,7 +211,8 @@ public:
|
||||
|
||||
if( r.use_count() != 0 )
|
||||
{
|
||||
pn = new boost::detail::local_counted_impl( std::move(r) );
|
||||
pn = new boost::detail::local_counted_impl( r._internal_count() );
|
||||
r.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,7 +231,7 @@ public:
|
||||
|
||||
if( px )
|
||||
{
|
||||
pn = new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) ) );
|
||||
pn = new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) )._internal_count() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,7 +454,7 @@ public:
|
||||
|
||||
if( pn )
|
||||
{
|
||||
return static_pointer_cast<Y>( pn->get_shared_ptr() );
|
||||
return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -502,7 +472,7 @@ public:
|
||||
|
||||
if( pn )
|
||||
{
|
||||
return static_pointer_cast<Y>( pn->get_shared_ptr() );
|
||||
return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -693,6 +663,13 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< ( std:
|
||||
|
||||
#endif // !defined(BOOST_NO_IOSTREAM)
|
||||
|
||||
// get_deleter
|
||||
|
||||
template<class D, class T> D * get_deleter( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return get_deleter<D>( shared_ptr<T>( p ) );
|
||||
}
|
||||
|
||||
// hash_value
|
||||
|
||||
template< class T > struct hash;
|
||||
|
17
include/boost/smart_ptr/make_local_shared.hpp
Normal file
17
include/boost/smart_ptr/make_local_shared.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_HPP_INCLUDED
|
||||
|
||||
// make_local_shared.hpp
|
||||
//
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/ for documentation.
|
||||
|
||||
#include <boost/smart_ptr/make_local_shared_object.hpp>
|
||||
#include <boost/smart_ptr/make_local_shared_array.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_HPP_INCLUDED
|
63
include/boost/smart_ptr/make_local_shared_array.hpp
Normal file
63
include/boost/smart_ptr/make_local_shared_array.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP_INCLUDED
|
||||
|
||||
// make_local_shared_array.hpp
|
||||
//
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/ for documentation.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct lsp_if_array
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct lsp_if_array<T[]>
|
||||
{
|
||||
typedef boost::local_shared_ptr<T[]> type;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N> struct lsp_if_array<T[N]>
|
||||
{
|
||||
typedef boost::local_shared_ptr<T[N]> type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T, class... Args> typename boost::detail::lsp_if_array<T>::type make_local_shared( Args&&... args )
|
||||
{
|
||||
return boost::make_shared<T>( std::forward<Args>(args)... );
|
||||
}
|
||||
|
||||
template<class T, class... Args> typename boost::detail::lsp_if_array<T>::type make_local_shared_noinit( Args&&... args )
|
||||
{
|
||||
return boost::make_shared_noinit<T>( std::forward<Args>(args)... );
|
||||
}
|
||||
|
||||
template<class T, class A, class... Args> typename boost::detail::lsp_if_array<T>::type allocate_local_shared( A const & a, Args&&... args )
|
||||
{
|
||||
return boost::allocate_shared<T>( a, std::forward<Args>(args)... );
|
||||
}
|
||||
|
||||
template<class T, class A, class... Args> typename boost::detail::lsp_if_array<T>::type allocate_local_shared_noinit( A const & a, Args&&... args )
|
||||
{
|
||||
return boost::allocate_shared_noinit<T>( a, std::forward<Args>(args)... );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
|
199
include/boost/smart_ptr/make_local_shared_object.hpp
Normal file
199
include/boost/smart_ptr/make_local_shared_object.hpp
Normal file
@ -0,0 +1,199 @@
|
||||
#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_OBJECT_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_OBJECT_HPP_INCLUDED
|
||||
|
||||
// make_local_shared_object.hpp
|
||||
//
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/ for documentation.
|
||||
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// lsp_if_not_array
|
||||
|
||||
template<class T> struct lsp_if_not_array
|
||||
{
|
||||
typedef boost::local_shared_ptr<T> type;
|
||||
};
|
||||
|
||||
template<class T> struct lsp_if_not_array<T[]>
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, std::size_t N> struct lsp_if_not_array<T[N]>
|
||||
{
|
||||
};
|
||||
|
||||
// lsp_ms_deleter
|
||||
|
||||
template<class T, class A> class lsp_ms_deleter: public local_counted_impl_em
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename sp_aligned_storage<sizeof(T), ::boost::alignment_of<T>::value>::type storage_type;
|
||||
|
||||
storage_type storage_;
|
||||
A a_;
|
||||
bool initialized_;
|
||||
|
||||
private:
|
||||
|
||||
void destroy() BOOST_SP_NOEXCEPT
|
||||
{
|
||||
if( initialized_ )
|
||||
{
|
||||
T * p = reinterpret_cast< T* >( storage_.data_ );
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
std::allocator_traits<A>::destroy( a_, p );
|
||||
|
||||
#else
|
||||
|
||||
p->~T();
|
||||
|
||||
#endif
|
||||
|
||||
initialized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
explicit lsp_ms_deleter( A const & a ) BOOST_SP_NOEXCEPT : a_( a ), initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
// optimization: do not copy storage_
|
||||
lsp_ms_deleter( lsp_ms_deleter const & r ) BOOST_SP_NOEXCEPT : a_( r.a_), initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
~lsp_ms_deleter() BOOST_SP_NOEXCEPT
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void operator()( T * ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
static void operator_fn( T* ) BOOST_SP_NOEXCEPT // operator() can't be static
|
||||
{
|
||||
}
|
||||
|
||||
void * address() BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return storage_.data_;
|
||||
}
|
||||
|
||||
void set_initialized() BOOST_SP_NOEXCEPT
|
||||
{
|
||||
initialized_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T, class A, class... Args> typename boost::detail::lsp_if_not_array<T>::type allocate_local_shared( A const & a, Args&&... args )
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
|
||||
|
||||
#else
|
||||
|
||||
typedef typename A::template rebind<T>::other A2;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
typedef boost::detail::lsp_ms_deleter<T, A2> D;
|
||||
|
||||
boost::shared_ptr<T> pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a2 );
|
||||
|
||||
D * pd = static_cast< D* >( pt._internal_get_untyped_deleter() );
|
||||
void * pv = pd->address();
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
std::allocator_traits<A2>::construct( a2, static_cast< T* >( pv ), std::forward<Args>( args )... );
|
||||
|
||||
#else
|
||||
|
||||
::new( pv ) T( std::forward<Args>( args )... );
|
||||
|
||||
#endif
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
|
||||
pd->pn_ = pt._internal_count();
|
||||
|
||||
return boost::local_shared_ptr<T>( boost::detail::lsp_internal_constructor_tag(), pt2, pd );
|
||||
}
|
||||
|
||||
template<class T, class A> typename boost::detail::lsp_if_not_array<T>::type allocate_local_shared_noinit( A const & a )
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
|
||||
|
||||
#else
|
||||
|
||||
typedef typename A::template rebind<T>::other A2;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
typedef boost::detail::lsp_ms_deleter<T, A2> D;
|
||||
|
||||
boost::shared_ptr<T> pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a2 );
|
||||
|
||||
D * pd = static_cast< D* >( pt._internal_get_untyped_deleter() );
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T;
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
|
||||
pd->pn_ = pt._internal_count();
|
||||
|
||||
return boost::local_shared_ptr<T>( boost::detail::lsp_internal_constructor_tag(), pt2, pd );
|
||||
}
|
||||
|
||||
template<class T, class... Args> typename boost::detail::lsp_if_not_array<T>::type make_local_shared( Args&&... args )
|
||||
{
|
||||
return boost::allocate_local_shared<T>( std::allocator<T>(), std::forward<Args>(args)... );
|
||||
}
|
||||
|
||||
template<class T> typename boost::detail::lsp_if_not_array<T>::type make_local_shared_noinit()
|
||||
{
|
||||
return boost::allocate_shared_noinit<T>( std::allocator<T>() );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
|
@ -323,6 +323,10 @@ template< class T, std::size_t N, class Y > inline void sp_deleter_construct( bo
|
||||
|
||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
struct sp_internal_constructor_tag
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@ -355,6 +359,18 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_CONSTEXPR shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count const & pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ )
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
BOOST_CONSTEXPR shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count && pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( std::move( pn_ ) )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y>
|
||||
@ -766,6 +782,11 @@ public:
|
||||
return pn.get_deleter( ti );
|
||||
}
|
||||
|
||||
void * _internal_get_local_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return pn.get_local_deleter( ti );
|
||||
}
|
||||
|
||||
void * _internal_get_untyped_deleter() const BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return pn.get_untyped_deleter();
|
||||
@ -776,6 +797,11 @@ public:
|
||||
return px == r.px && pn == r.pn;
|
||||
}
|
||||
|
||||
boost::detail::shared_count _internal_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn;
|
||||
}
|
||||
|
||||
// Tasteless as this may seem, making all members public allows member templates
|
||||
// to work in the absence of member template friends. (Matthew Langston)
|
||||
|
||||
@ -980,27 +1006,13 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
||||
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
|
||||
( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
|
||||
|
||||
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
|
||||
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
|
||||
|
||||
template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
|
||||
{
|
||||
void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
|
||||
return const_cast<D *>(static_cast<D const *>(q));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) );
|
||||
}
|
||||
|
||||
#endif
|
||||
template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT;
|
||||
template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT;
|
||||
|
||||
class esft2_deleter_wrapper
|
||||
{
|
||||
@ -1035,17 +1047,22 @@ public:
|
||||
|
||||
template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
D *del = boost::detail::basic_get_deleter<D>(p);
|
||||
D * d = boost::detail::basic_get_deleter<D>( p );
|
||||
|
||||
if(del == 0)
|
||||
if( d == 0 )
|
||||
{
|
||||
d = boost::detail::basic_get_local_deleter( d, p );
|
||||
}
|
||||
|
||||
if( d == 0 )
|
||||
{
|
||||
boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p);
|
||||
// The following get_deleter method call is fully qualified because
|
||||
// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
|
||||
if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
|
||||
if(del_wrapper) d = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
|
||||
}
|
||||
|
||||
return del;
|
||||
return d;
|
||||
}
|
||||
|
||||
// atomic access
|
||||
@ -1138,6 +1155,28 @@ template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOO
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/smart_ptr/detail/local_sp_deleter.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID(local_sp_deleter<D>) ) );
|
||||
}
|
||||
|
||||
template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID(local_sp_deleter<D>) ) );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
@ -230,5 +230,18 @@ import testing ;
|
||||
[ run lsp_array_n_test.cpp ]
|
||||
[ run lsp_array_cv_test.cpp ]
|
||||
[ run lsp_array_cast_test.cpp ]
|
||||
|
||||
[ run get_local_deleter_test.cpp ]
|
||||
[ run get_local_deleter_test2.cpp ]
|
||||
[ run get_local_deleter_test3.cpp ]
|
||||
[ run get_local_deleter_array_test.cpp ]
|
||||
[ run get_local_deleter_array_test2.cpp ]
|
||||
|
||||
[ run make_local_shared_test.cpp ]
|
||||
[ run make_local_shared_esft_test.cpp ]
|
||||
[ run allocate_local_shared_test.cpp ]
|
||||
[ run allocate_local_shared_esft_test.cpp ]
|
||||
|
||||
[ run local_sp_fn_test.cpp ]
|
||||
;
|
||||
}
|
||||
|
298
test/allocate_local_shared_esft_test.cpp
Normal file
298
test/allocate_local_shared_esft_test.cpp
Normal file
@ -0,0 +1,298 @@
|
||||
// allocate_local_shared_esft_test.cpp
|
||||
//
|
||||
// Copyright 2007-2009, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/smart_ptr/make_local_shared.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <memory>
|
||||
|
||||
class X: public boost::enable_shared_from_this<X>
|
||||
{
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
|
||||
public:
|
||||
|
||||
static int instances;
|
||||
|
||||
explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>() );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared_noinit< X >( std::allocator<void>() );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( px, qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
235
test/allocate_local_shared_test.cpp
Normal file
235
test/allocate_local_shared_test.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
// allocate_local_shared_test.cpp
|
||||
//
|
||||
// Copyright 2007-2009, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/smart_ptr/make_local_shared.hpp>
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
class X
|
||||
{
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
|
||||
void * operator new( std::size_t n )
|
||||
{
|
||||
// lack of this definition causes link errors on Comeau C++
|
||||
BOOST_ERROR( "private X::new called" );
|
||||
return ::operator new( n );
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
// lack of this definition causes link errors on MSVC
|
||||
BOOST_ERROR( "private X::delete called" );
|
||||
::operator delete( p );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static int instances;
|
||||
|
||||
int v;
|
||||
|
||||
explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::local_shared_ptr< int > pi = boost::allocate_local_shared< int >( std::allocator<int>() );
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( *pi == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< int > pi = boost::allocate_local_shared_noinit< int >( std::allocator<int>() );
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< int > pi = boost::allocate_local_shared< int >( std::allocator<int>(), 5 );
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( *pi == 5 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>() );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 0 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared_noinit< X >( std::allocator<void>() );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 0 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
@ -62,6 +62,28 @@ int main()
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_shared_noinit< X >( std::allocator<void>() );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
@ -61,6 +61,12 @@ int main()
|
||||
BOOST_TEST( *pi == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< int > pi = boost::allocate_shared_noinit< int >( std::allocator<int>() );
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator<int>(), 5 );
|
||||
|
||||
@ -83,6 +89,19 @@ int main()
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared_noinit< X >( std::allocator<void>() );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 0 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
151
test/get_local_deleter_array_test.cpp
Normal file
151
test/get_local_deleter_array_test.cpp
Normal file
@ -0,0 +1,151 @@
|
||||
//
|
||||
// get_local_deleter_array_test2.cpp
|
||||
//
|
||||
// Copyright 2002, 2011, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct deleter
|
||||
{
|
||||
int data;
|
||||
|
||||
deleter(): data(0)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(void *)
|
||||
{
|
||||
BOOST_TEST(data == 17041);
|
||||
}
|
||||
};
|
||||
|
||||
struct deleter2
|
||||
{
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::local_shared_ptr<X[]> p;
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr<X[1]> p;
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr<X[]> p(new X[1]);
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr<X[1]> p(new X[1]);
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
X x[1];
|
||||
boost::local_shared_ptr<X[]> p(x, deleter());
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
|
||||
deleter * q = boost::get_deleter<deleter>(p);
|
||||
|
||||
BOOST_TEST(q != 0);
|
||||
BOOST_TEST(q->data == 0);
|
||||
|
||||
q->data = 17041;
|
||||
|
||||
deleter const * r = boost::get_deleter<deleter const>(p);
|
||||
|
||||
BOOST_TEST(r == q);
|
||||
BOOST_TEST(r->data == 17041);
|
||||
}
|
||||
|
||||
{
|
||||
X x[1];
|
||||
boost::local_shared_ptr<X[1]> p(x, deleter());
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
|
||||
deleter * q = boost::get_deleter<deleter>(p);
|
||||
|
||||
BOOST_TEST(q != 0);
|
||||
BOOST_TEST(q->data == 0);
|
||||
|
||||
q->data = 17041;
|
||||
|
||||
deleter const * r = boost::get_deleter<deleter const>(p);
|
||||
|
||||
BOOST_TEST(r == q);
|
||||
BOOST_TEST(r->data == 17041);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
74
test/get_local_deleter_array_test2.cpp
Normal file
74
test/get_local_deleter_array_test2.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// get_local_deleter_test2.cpp
|
||||
//
|
||||
// Copyright 2002, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_local_shared.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct deleter
|
||||
{
|
||||
};
|
||||
|
||||
struct deleter2;
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::local_shared_ptr<X[]> p = boost::make_local_shared<X[]>( 1 );
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr<X[1]> p = boost::make_local_shared<X[1]>();
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
struct deleter2
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
95
test/get_local_deleter_test.cpp
Normal file
95
test/get_local_deleter_test.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// get_local_deleter_test.cpp
|
||||
//
|
||||
// Copyright 2002, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct deleter
|
||||
{
|
||||
int data;
|
||||
|
||||
deleter(): data(0)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(void *)
|
||||
{
|
||||
BOOST_TEST(data == 17041);
|
||||
}
|
||||
};
|
||||
|
||||
struct deleter2
|
||||
{
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::local_shared_ptr<X> p;
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr<X> p(new X);
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
boost::local_shared_ptr<X> p(&x, deleter());
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
|
||||
deleter * q = boost::get_deleter<deleter>(p);
|
||||
|
||||
BOOST_TEST(q != 0);
|
||||
BOOST_TEST(q->data == 0);
|
||||
|
||||
q->data = 17041;
|
||||
|
||||
deleter const * r = boost::get_deleter<deleter const>(p);
|
||||
|
||||
BOOST_TEST(r == q);
|
||||
BOOST_TEST(r->data == 17041);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
43
test/get_local_deleter_test2.cpp
Normal file
43
test/get_local_deleter_test2.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// get_local_deleter_test2.cpp
|
||||
//
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct deleter;
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
static void test_lsp_get_deleter( boost::local_shared_ptr<X> const & p )
|
||||
{
|
||||
BOOST_TEST( boost::get_deleter<deleter>( p ) != 0 );
|
||||
}
|
||||
|
||||
static void test_sp_get_deleter( boost::shared_ptr<X> const & p )
|
||||
{
|
||||
BOOST_TEST( boost::get_deleter<deleter>( p ) != 0 );
|
||||
}
|
||||
|
||||
struct deleter
|
||||
{
|
||||
void operator()( X const * p ) { delete p; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::local_shared_ptr<X> p( new X, deleter() );
|
||||
|
||||
test_lsp_get_deleter( p );
|
||||
test_sp_get_deleter( p );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
59
test/get_local_deleter_test3.cpp
Normal file
59
test/get_local_deleter_test3.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// get_local_deleter_test3.cpp
|
||||
//
|
||||
// Copyright 2002, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_local_shared.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct deleter
|
||||
{
|
||||
};
|
||||
|
||||
struct deleter2;
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::local_shared_ptr<X> p = boost::make_local_shared<X>();
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
struct deleter2
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
43
test/local_sp_fn_test.cpp
Normal file
43
test/local_sp_fn_test.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// local_sp_fn_test.cpp
|
||||
//
|
||||
// Copyright 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
static void f()
|
||||
{
|
||||
}
|
||||
|
||||
struct null_deleter
|
||||
{
|
||||
template<class Y> void operator()( Y* ) {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::local_shared_ptr<void()> pf( f, null_deleter() );
|
||||
|
||||
BOOST_TEST( pf.get() == f );
|
||||
BOOST_TEST_EQ( pf.local_use_count(), 1 );
|
||||
BOOST_TEST( boost::get_deleter<null_deleter>( pf ) != 0 );
|
||||
|
||||
boost::weak_ptr<void()> wp( pf );
|
||||
|
||||
BOOST_TEST( wp.lock().get() == f );
|
||||
BOOST_TEST_EQ( wp.use_count(), 1 );
|
||||
|
||||
pf.reset();
|
||||
|
||||
BOOST_TEST( wp.lock().get() == 0 );
|
||||
BOOST_TEST_EQ( wp.use_count(), 0 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -9,6 +9,8 @@
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct X
|
||||
@ -1679,6 +1681,809 @@ static void shared_ptr_move_assignment()
|
||||
|
||||
#endif
|
||||
|
||||
// unique_ptr assignment
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||
|
||||
template<class T> static void empty_unique_ptr_assign_test()
|
||||
{
|
||||
boost::local_shared_ptr<T> p2;
|
||||
|
||||
p2 = std::unique_ptr<T>();
|
||||
|
||||
BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) );
|
||||
BOOST_TEST_EQ( p2.local_use_count(), 0 );
|
||||
|
||||
boost::local_shared_ptr<T const> p3;
|
||||
|
||||
p3 = std::unique_ptr<T>();
|
||||
|
||||
BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) );
|
||||
BOOST_TEST_EQ( p3.local_use_count(), 0 );
|
||||
|
||||
boost::local_shared_ptr<void> p4;
|
||||
|
||||
p4 = std::unique_ptr<T>();
|
||||
|
||||
BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) );
|
||||
BOOST_TEST_EQ( p4.local_use_count(), 0 );
|
||||
|
||||
boost::local_shared_ptr<void const> p5;
|
||||
|
||||
p5 = std::unique_ptr<T const>();
|
||||
|
||||
BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) );
|
||||
BOOST_TEST_EQ( p5.local_use_count(), 0 );
|
||||
}
|
||||
|
||||
template<class T> static void empty_unique_ptr_assign_test_()
|
||||
{
|
||||
boost::local_shared_ptr<T> p2( static_cast<T*>(0) );
|
||||
|
||||
p2 = std::unique_ptr<T>();
|
||||
|
||||
BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) );
|
||||
BOOST_TEST_EQ( p2.local_use_count(), 0 );
|
||||
|
||||
boost::local_shared_ptr<T const> p3( static_cast<T const*>(0) );
|
||||
|
||||
p3 = std::unique_ptr<T>();
|
||||
|
||||
BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) );
|
||||
BOOST_TEST_EQ( p3.local_use_count(), 0 );
|
||||
|
||||
boost::local_shared_ptr<void> p4( static_cast<T*>(0) );
|
||||
|
||||
p4 = std::unique_ptr<T>();
|
||||
|
||||
BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) );
|
||||
BOOST_TEST_EQ( p4.local_use_count(), 0 );
|
||||
|
||||
boost::local_shared_ptr<void const> p5( static_cast<T const*>(0) );
|
||||
|
||||
p5 = std::unique_ptr<T const>();
|
||||
|
||||
BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) );
|
||||
BOOST_TEST_EQ( p5.local_use_count(), 0 );
|
||||
}
|
||||
|
||||
template<class T, class U, class D> static void test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T> p2, std::unique_ptr<U, D> && p1 )
|
||||
{
|
||||
U* q = p1.get();
|
||||
|
||||
p2 = std::move( p1 );
|
||||
|
||||
BOOST_TEST_EQ( p2.get(), q );
|
||||
BOOST_TEST_EQ( p2.local_use_count(), 1 );
|
||||
|
||||
BOOST_TEST( p1.get() == 0 );
|
||||
}
|
||||
|
||||
template<class T> static void new_unique_ptr_assign_test()
|
||||
{
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>(), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>(), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>(), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>(), std::unique_ptr<T>( new T() ) );
|
||||
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), std::unique_ptr<T>( new T() ) );
|
||||
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>( new T() ), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>( new T const() ), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>( new T volatile() ), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ), std::unique_ptr<T>( new T() ) );
|
||||
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void>(), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void const>(), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void volatile>(), std::unique_ptr<T>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void const volatile>(), std::unique_ptr<T>( new T() ) );
|
||||
}
|
||||
|
||||
template<class T> static void del_unique_ptr_assign_test()
|
||||
{
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>( new T() ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>( new T const() ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>( new T volatile() ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void const>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void volatile>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void const volatile>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) );
|
||||
}
|
||||
|
||||
static void unique_ptr_assignment()
|
||||
{
|
||||
empty_unique_ptr_assign_test<int>();
|
||||
empty_unique_ptr_assign_test_<int>();
|
||||
empty_unique_ptr_assign_test<X>();
|
||||
empty_unique_ptr_assign_test_<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
new_unique_ptr_assign_test<int>();
|
||||
new_unique_ptr_assign_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
del_unique_ptr_assign_test<int>();
|
||||
del_unique_ptr_assign_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void unique_ptr_assignment()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// pointer reset
|
||||
|
||||
template<class T, class U> static void test_pointer_reset( boost::local_shared_ptr<U> p2 )
|
||||
{
|
||||
T * q = new T();
|
||||
|
||||
p2.reset( q );
|
||||
|
||||
BOOST_TEST_EQ( p2.get(), q );
|
||||
BOOST_TEST_EQ( p2.local_use_count(), 1 );
|
||||
}
|
||||
|
||||
template<class T> static void empty_pointer_reset_test()
|
||||
{
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T>() );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T const>() );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T volatile>() );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T const volatile>() );
|
||||
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void>() );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void const>() );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void volatile>() );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void const volatile>() );
|
||||
}
|
||||
|
||||
template<class T> static void null_pointer_reset_test()
|
||||
{
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T const>( static_cast<T*>(0) ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T volatile>( static_cast<T*>(0) ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T const volatile>( static_cast<T*>(0) ) );
|
||||
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void>( static_cast<T*>(0) ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void const>( static_cast<T*>(0) ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void volatile>( static_cast<T*>(0) ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void const volatile>( static_cast<T*>(0) ) );
|
||||
}
|
||||
|
||||
template<class T> static void new_pointer_reset_test()
|
||||
{
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T>( new T() ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T const>( new T() ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T volatile>( new T() ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<T const volatile>( new T() ) );
|
||||
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void>( new T() ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void const>( new T() ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void volatile>( new T() ) );
|
||||
test_pointer_reset<T>( boost::local_shared_ptr<void const volatile>( new T() ) );
|
||||
}
|
||||
|
||||
static void pointer_reset()
|
||||
{
|
||||
empty_pointer_reset_test<int>();
|
||||
empty_pointer_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
null_pointer_reset_test<int>();
|
||||
null_pointer_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
new_pointer_reset_test<int>();
|
||||
new_pointer_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
// deleter reset
|
||||
|
||||
template<class T> class deleter
|
||||
{
|
||||
private:
|
||||
|
||||
bool * called_;
|
||||
|
||||
public:
|
||||
|
||||
explicit deleter( bool * called ): called_( called ) {}
|
||||
void operator()( T * p ) { *called_ = true; delete p; }
|
||||
};
|
||||
|
||||
template<class T, class U> static void test_deleter_reset( boost::local_shared_ptr<U> p2 )
|
||||
{
|
||||
T * q = new T();
|
||||
|
||||
bool called = false;
|
||||
|
||||
p2.reset( q, deleter<T>( &called ) );
|
||||
|
||||
BOOST_TEST_EQ( p2.get(), q );
|
||||
BOOST_TEST_EQ( p2.local_use_count(), 1 );
|
||||
|
||||
boost::shared_ptr<U> p3( p2 );
|
||||
|
||||
BOOST_TEST( boost::get_deleter< deleter<T> >( p3 ) != 0 );
|
||||
|
||||
p3.reset();
|
||||
BOOST_TEST( !called );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( called );
|
||||
}
|
||||
|
||||
template<class T> static void empty_deleter_reset_test()
|
||||
{
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T>() );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T const>() );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T volatile>() );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T const volatile>() );
|
||||
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void>() );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void const>() );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void volatile>() );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void const volatile>() );
|
||||
}
|
||||
|
||||
template<class T> static void null_deleter_reset_test()
|
||||
{
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T const>( static_cast<T*>(0) ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T volatile>( static_cast<T*>(0) ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T const volatile>( static_cast<T*>(0) ) );
|
||||
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void>( static_cast<T*>(0) ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void const>( static_cast<T*>(0) ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void volatile>( static_cast<T*>(0) ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void const volatile>( static_cast<T*>(0) ) );
|
||||
}
|
||||
|
||||
template<class T> static void new_deleter_reset_test()
|
||||
{
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T>( new T() ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T const>( new T() ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T volatile>( new T() ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<T const volatile>( new T() ) );
|
||||
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void>( new T() ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void const>( new T() ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void volatile>( new T() ) );
|
||||
test_deleter_reset<T>( boost::local_shared_ptr<void const volatile>( new T() ) );
|
||||
}
|
||||
|
||||
static void deleter_reset()
|
||||
{
|
||||
empty_deleter_reset_test<int>();
|
||||
empty_deleter_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
null_deleter_reset_test<int>();
|
||||
null_deleter_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
new_deleter_reset_test<int>();
|
||||
new_deleter_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
// allocator reset
|
||||
|
||||
template<class T, class U> static void test_allocator_reset( boost::local_shared_ptr<U> p2 )
|
||||
{
|
||||
T * q = new T();
|
||||
|
||||
bool called = false;
|
||||
|
||||
p2.reset( q, deleter<T>( &called ), std::allocator<T>() );
|
||||
|
||||
BOOST_TEST_EQ( p2.get(), q );
|
||||
BOOST_TEST_EQ( p2.local_use_count(), 1 );
|
||||
|
||||
boost::shared_ptr<U> p3( p2 );
|
||||
|
||||
BOOST_TEST( boost::get_deleter< deleter<T> >( p3 ) != 0 );
|
||||
|
||||
p3.reset();
|
||||
BOOST_TEST( !called );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( called );
|
||||
}
|
||||
|
||||
template<class T> static void empty_allocator_reset_test()
|
||||
{
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T>() );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T const>() );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T volatile>() );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T const volatile>() );
|
||||
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void>() );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void const>() );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void volatile>() );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void const volatile>() );
|
||||
}
|
||||
|
||||
template<class T> static void null_allocator_reset_test()
|
||||
{
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T const>( static_cast<T*>(0) ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T volatile>( static_cast<T*>(0) ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T const volatile>( static_cast<T*>(0) ) );
|
||||
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void>( static_cast<T*>(0) ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void const>( static_cast<T*>(0) ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void volatile>( static_cast<T*>(0) ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void const volatile>( static_cast<T*>(0) ) );
|
||||
}
|
||||
|
||||
template<class T> static void new_allocator_reset_test()
|
||||
{
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T>( new T() ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T const>( new T() ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T volatile>( new T() ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<T const volatile>( new T() ) );
|
||||
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void>( new T() ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void const>( new T() ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void volatile>( new T() ) );
|
||||
test_allocator_reset<T>( boost::local_shared_ptr<void const volatile>( new T() ) );
|
||||
}
|
||||
|
||||
static void allocator_reset()
|
||||
{
|
||||
empty_allocator_reset_test<int>();
|
||||
empty_allocator_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
null_allocator_reset_test<int>();
|
||||
null_allocator_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
new_allocator_reset_test<int>();
|
||||
new_allocator_reset_test<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
// aliasing reset
|
||||
|
||||
struct null_deleter
|
||||
{
|
||||
void operator()( void const volatile* ) {}
|
||||
};
|
||||
|
||||
template<class T, class U> void test_aliasing_reset_( boost::local_shared_ptr<T> const & p1, U * p2 )
|
||||
{
|
||||
boost::local_shared_ptr<U> p3( static_cast<U*>(0), null_deleter() );
|
||||
|
||||
p3.reset( p1, p2 );
|
||||
|
||||
BOOST_TEST( p3.get() == p2 );
|
||||
BOOST_TEST( p3.local_use_count() == p1.local_use_count() );
|
||||
BOOST_TEST( !p3.owner_before( p1 ) && !p1.owner_before( p3 ) );
|
||||
}
|
||||
|
||||
template<class T, class U> void test_01_aliasing_reset_()
|
||||
{
|
||||
U u;
|
||||
boost::local_shared_ptr<T> p1;
|
||||
|
||||
test_aliasing_reset_( p1, &u );
|
||||
}
|
||||
|
||||
template<class T, class U> void test_01_aliasing_reset()
|
||||
{
|
||||
test_01_aliasing_reset_<T, U>();
|
||||
test_01_aliasing_reset_<T const, U>();
|
||||
test_01_aliasing_reset_<T volatile, U>();
|
||||
test_01_aliasing_reset_<T const volatile, U>();
|
||||
|
||||
test_01_aliasing_reset_<T, U volatile>();
|
||||
test_01_aliasing_reset_<T const, U volatile>();
|
||||
test_01_aliasing_reset_<T volatile, U volatile>();
|
||||
test_01_aliasing_reset_<T const volatile, U volatile>();
|
||||
}
|
||||
|
||||
template<class T, class U> void test_10_aliasing_reset_()
|
||||
{
|
||||
boost::local_shared_ptr<T> p1( new T() );
|
||||
test_aliasing_reset_( p1, static_cast<U*>(0) );
|
||||
}
|
||||
|
||||
template<class T, class U> void test_10_aliasing_reset()
|
||||
{
|
||||
test_10_aliasing_reset_<T, U>();
|
||||
test_10_aliasing_reset_<T const, U>();
|
||||
test_10_aliasing_reset_<T volatile, U>();
|
||||
test_10_aliasing_reset_<T const volatile, U>();
|
||||
|
||||
test_10_aliasing_reset_<T, U const>();
|
||||
test_10_aliasing_reset_<T const, U const>();
|
||||
test_10_aliasing_reset_<T volatile, U const>();
|
||||
test_10_aliasing_reset_<T const volatile, U const>();
|
||||
|
||||
test_10_aliasing_reset_<T, U volatile>();
|
||||
test_10_aliasing_reset_<T const, U volatile>();
|
||||
test_10_aliasing_reset_<T volatile, U volatile>();
|
||||
test_10_aliasing_reset_<T const volatile, U volatile>();
|
||||
|
||||
test_10_aliasing_reset_<T, U const volatile>();
|
||||
test_10_aliasing_reset_<T const, U const volatile>();
|
||||
test_10_aliasing_reset_<T volatile, U const volatile>();
|
||||
test_10_aliasing_reset_<T const volatile, U const volatile>();
|
||||
}
|
||||
|
||||
template<class T, class U> void test_11_aliasing_reset_()
|
||||
{
|
||||
U u;
|
||||
boost::local_shared_ptr<T> p1( new T() );
|
||||
|
||||
test_aliasing_reset_( p1, &u );
|
||||
}
|
||||
|
||||
template<class T, class U> void test_11_aliasing_reset()
|
||||
{
|
||||
test_11_aliasing_reset_<T, U>();
|
||||
test_11_aliasing_reset_<T const, U>();
|
||||
test_11_aliasing_reset_<T volatile, U>();
|
||||
test_11_aliasing_reset_<T const volatile, U>();
|
||||
|
||||
test_11_aliasing_reset_<T, U volatile>();
|
||||
test_11_aliasing_reset_<T const, U volatile>();
|
||||
test_11_aliasing_reset_<T volatile, U volatile>();
|
||||
test_11_aliasing_reset_<T const volatile, U volatile>();
|
||||
}
|
||||
|
||||
static void aliasing_reset()
|
||||
{
|
||||
test_01_aliasing_reset<int, int>();
|
||||
test_10_aliasing_reset<int, int>();
|
||||
test_11_aliasing_reset<int, int>();
|
||||
|
||||
test_01_aliasing_reset<void, int>();
|
||||
|
||||
test_10_aliasing_reset<int, void>();
|
||||
|
||||
test_10_aliasing_reset<int, incomplete>();
|
||||
|
||||
test_01_aliasing_reset<X, X>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_10_aliasing_reset<X, X>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_11_aliasing_reset<X, X>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_01_aliasing_reset<int, X>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_10_aliasing_reset<int, X>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_11_aliasing_reset<int, X>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_01_aliasing_reset<X, int>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_10_aliasing_reset<X, int>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_11_aliasing_reset<X, int>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_01_aliasing_reset<void, X>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_10_aliasing_reset<X, void>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
test_10_aliasing_reset<X, incomplete>();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
// element access
|
||||
|
||||
template<class T> static void empty_element_access_()
|
||||
{
|
||||
boost::local_shared_ptr<T> p1;
|
||||
|
||||
BOOST_TEST_EQ( p1.operator->(), static_cast<T*>(0) );
|
||||
BOOST_TEST_EQ( p1.get(), static_cast<T*>(0) );
|
||||
BOOST_TEST( p1? false: true );
|
||||
BOOST_TEST( !p1 );
|
||||
BOOST_TEST_EQ( p1.local_use_count(), 0 );
|
||||
}
|
||||
|
||||
template<class T> static void empty_element_access()
|
||||
{
|
||||
empty_element_access_<T>();
|
||||
empty_element_access_<T const>();
|
||||
empty_element_access_<T volatile>();
|
||||
empty_element_access_<T const volatile>();
|
||||
}
|
||||
|
||||
template<class T> static void new_element_access_()
|
||||
{
|
||||
{
|
||||
T * p0 = new T();
|
||||
boost::local_shared_ptr<T> p1( p0 );
|
||||
|
||||
BOOST_TEST_EQ( p1.operator->(), p0 );
|
||||
BOOST_TEST_EQ( p1.get(), p0 );
|
||||
BOOST_TEST_EQ( &*p1, p0 );
|
||||
BOOST_TEST( p1? true: false );
|
||||
BOOST_TEST_NOT( !p1 );
|
||||
BOOST_TEST_EQ( p1.local_use_count(), 1 );
|
||||
}
|
||||
|
||||
{
|
||||
T * p0 = new T[3]();
|
||||
boost::local_shared_ptr<T[]> p1( p0 );
|
||||
|
||||
BOOST_TEST_EQ( p1.get(), p0 );
|
||||
|
||||
BOOST_TEST_EQ( &p1[0], &p0[0] );
|
||||
BOOST_TEST_EQ( &p1[1], &p0[1] );
|
||||
BOOST_TEST_EQ( &p1[2], &p0[2] );
|
||||
|
||||
BOOST_TEST( p1? true: false );
|
||||
BOOST_TEST_NOT( !p1 );
|
||||
BOOST_TEST_EQ( p1.local_use_count(), 1 );
|
||||
}
|
||||
|
||||
{
|
||||
T * p0 = new T[3]();
|
||||
boost::local_shared_ptr<T[3]> p1( p0 );
|
||||
|
||||
BOOST_TEST_EQ( p1.get(), p0 );
|
||||
|
||||
BOOST_TEST_EQ( &p1[0], &p0[0] );
|
||||
BOOST_TEST_EQ( &p1[1], &p0[1] );
|
||||
BOOST_TEST_EQ( &p1[2], &p0[2] );
|
||||
|
||||
BOOST_TEST( p1? true: false );
|
||||
BOOST_TEST_NOT( !p1 );
|
||||
BOOST_TEST_EQ( p1.local_use_count(), 1 );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> static void new_element_access()
|
||||
{
|
||||
new_element_access_<T>();
|
||||
new_element_access_<T const>();
|
||||
new_element_access_<T volatile>();
|
||||
new_element_access_<T const volatile>();
|
||||
}
|
||||
|
||||
static void element_access()
|
||||
{
|
||||
empty_element_access<int>();
|
||||
empty_element_access<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
empty_element_access<incomplete>();
|
||||
empty_element_access<void>();
|
||||
|
||||
new_element_access<int>();
|
||||
new_element_access<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
// shared_ptr conversion
|
||||
|
||||
template<class T, class U> static void empty_shared_ptr_conversion_()
|
||||
{
|
||||
boost::local_shared_ptr<T> p1;
|
||||
boost::shared_ptr<U> p2( p1 );
|
||||
|
||||
BOOST_TEST_EQ( p2.get(), static_cast<U*>(0) );
|
||||
BOOST_TEST_EQ( p2.use_count(), 0 );
|
||||
}
|
||||
|
||||
template<class T> static void empty_shared_ptr_conversion()
|
||||
{
|
||||
empty_shared_ptr_conversion_<T, T>();
|
||||
empty_shared_ptr_conversion_<T, T const>();
|
||||
empty_shared_ptr_conversion_<T, T volatile>();
|
||||
empty_shared_ptr_conversion_<T, T const volatile>();
|
||||
|
||||
empty_shared_ptr_conversion_<T const, T const>();
|
||||
empty_shared_ptr_conversion_<T volatile, T volatile>();
|
||||
empty_shared_ptr_conversion_<T const volatile, T const volatile>();
|
||||
|
||||
empty_shared_ptr_conversion_<T, void>();
|
||||
empty_shared_ptr_conversion_<T, void const>();
|
||||
empty_shared_ptr_conversion_<T, void volatile>();
|
||||
empty_shared_ptr_conversion_<T, void const volatile>();
|
||||
|
||||
empty_shared_ptr_conversion_<T const, void const>();
|
||||
empty_shared_ptr_conversion_<T volatile, void volatile>();
|
||||
empty_shared_ptr_conversion_<T const volatile, void const volatile>();
|
||||
}
|
||||
|
||||
template<class T, class U> static void new_shared_ptr_conversion_()
|
||||
{
|
||||
boost::local_shared_ptr<T> p1( new T() );
|
||||
boost::shared_ptr<U> p2( p1 );
|
||||
|
||||
BOOST_TEST_EQ( p2.get(), p1.get() );
|
||||
BOOST_TEST_EQ( p2.use_count(), 2 );
|
||||
|
||||
boost::shared_ptr<U> p3( p1 );
|
||||
|
||||
BOOST_TEST_EQ( p3.get(), p1.get() );
|
||||
BOOST_TEST_EQ( p3.use_count(), 3 );
|
||||
BOOST_TEST( !(p2 < p3) && !(p3 < p2) );
|
||||
|
||||
BOOST_TEST_EQ( p1.local_use_count(), 1 );
|
||||
|
||||
p1.reset();
|
||||
|
||||
BOOST_TEST_EQ( p2.use_count(), 2 );
|
||||
BOOST_TEST_EQ( p3.use_count(), 2 );
|
||||
}
|
||||
|
||||
template<class T> static void new_shared_ptr_conversion()
|
||||
{
|
||||
new_shared_ptr_conversion_<T, T>();
|
||||
new_shared_ptr_conversion_<T, T const>();
|
||||
new_shared_ptr_conversion_<T, T volatile>();
|
||||
new_shared_ptr_conversion_<T, T const volatile>();
|
||||
|
||||
new_shared_ptr_conversion_<T const, T const>();
|
||||
new_shared_ptr_conversion_<T volatile, T volatile>();
|
||||
new_shared_ptr_conversion_<T const volatile, T const volatile>();
|
||||
|
||||
new_shared_ptr_conversion_<T, void>();
|
||||
new_shared_ptr_conversion_<T, void const>();
|
||||
new_shared_ptr_conversion_<T, void volatile>();
|
||||
new_shared_ptr_conversion_<T, void const volatile>();
|
||||
|
||||
new_shared_ptr_conversion_<T const, void const>();
|
||||
new_shared_ptr_conversion_<T volatile, void volatile>();
|
||||
new_shared_ptr_conversion_<T const volatile, void const volatile>();
|
||||
}
|
||||
|
||||
static void shared_ptr_conversion()
|
||||
{
|
||||
empty_shared_ptr_conversion<void>();
|
||||
empty_shared_ptr_conversion<incomplete>();
|
||||
empty_shared_ptr_conversion<int>();
|
||||
empty_shared_ptr_conversion<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
new_shared_ptr_conversion<int>();
|
||||
new_shared_ptr_conversion<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
// weak_ptr conversion
|
||||
|
||||
template<class T, class U> static void empty_weak_ptr_conversion_()
|
||||
{
|
||||
boost::local_shared_ptr<T> p1;
|
||||
boost::weak_ptr<U> p2( p1 );
|
||||
|
||||
BOOST_TEST_EQ( p2.lock().get(), static_cast<U*>(0) );
|
||||
BOOST_TEST_EQ( p2.use_count(), 0 );
|
||||
}
|
||||
|
||||
template<class T> static void empty_weak_ptr_conversion()
|
||||
{
|
||||
empty_weak_ptr_conversion_<T, T>();
|
||||
empty_weak_ptr_conversion_<T, T const>();
|
||||
empty_weak_ptr_conversion_<T, T volatile>();
|
||||
empty_weak_ptr_conversion_<T, T const volatile>();
|
||||
|
||||
empty_weak_ptr_conversion_<T const, T const>();
|
||||
empty_weak_ptr_conversion_<T volatile, T volatile>();
|
||||
empty_weak_ptr_conversion_<T const volatile, T const volatile>();
|
||||
|
||||
empty_weak_ptr_conversion_<T, void>();
|
||||
empty_weak_ptr_conversion_<T, void const>();
|
||||
empty_weak_ptr_conversion_<T, void volatile>();
|
||||
empty_weak_ptr_conversion_<T, void const volatile>();
|
||||
|
||||
empty_weak_ptr_conversion_<T const, void const>();
|
||||
empty_weak_ptr_conversion_<T volatile, void volatile>();
|
||||
empty_weak_ptr_conversion_<T const volatile, void const volatile>();
|
||||
}
|
||||
|
||||
template<class T, class U> static void new_weak_ptr_conversion_()
|
||||
{
|
||||
boost::local_shared_ptr<T> p1( new T() );
|
||||
boost::weak_ptr<U> p2( p1 );
|
||||
|
||||
BOOST_TEST_EQ( p2.lock().get(), p1.get() );
|
||||
BOOST_TEST_EQ( p2.use_count(), 1 );
|
||||
|
||||
boost::weak_ptr<U> p3( p1 );
|
||||
|
||||
BOOST_TEST_EQ( p3.lock().get(), p1.get() );
|
||||
BOOST_TEST_EQ( p3.use_count(), 1 );
|
||||
BOOST_TEST( !(p2 < p3) && !(p3 < p2) );
|
||||
|
||||
BOOST_TEST_EQ( p1.local_use_count(), 1 );
|
||||
|
||||
p1.reset();
|
||||
|
||||
BOOST_TEST_EQ( p2.use_count(), 0 );
|
||||
BOOST_TEST_EQ( p3.use_count(), 0 );
|
||||
}
|
||||
|
||||
template<class T> static void new_weak_ptr_conversion()
|
||||
{
|
||||
new_weak_ptr_conversion_<T, T>();
|
||||
new_weak_ptr_conversion_<T, T const>();
|
||||
new_weak_ptr_conversion_<T, T volatile>();
|
||||
new_weak_ptr_conversion_<T, T const volatile>();
|
||||
|
||||
new_weak_ptr_conversion_<T const, T const>();
|
||||
new_weak_ptr_conversion_<T volatile, T volatile>();
|
||||
new_weak_ptr_conversion_<T const volatile, T const volatile>();
|
||||
|
||||
new_weak_ptr_conversion_<T, void>();
|
||||
new_weak_ptr_conversion_<T, void const>();
|
||||
new_weak_ptr_conversion_<T, void volatile>();
|
||||
new_weak_ptr_conversion_<T, void const volatile>();
|
||||
|
||||
new_weak_ptr_conversion_<T const, void const>();
|
||||
new_weak_ptr_conversion_<T volatile, void volatile>();
|
||||
new_weak_ptr_conversion_<T const volatile, void const volatile>();
|
||||
}
|
||||
|
||||
static void weak_ptr_conversion()
|
||||
{
|
||||
empty_weak_ptr_conversion<void>();
|
||||
empty_weak_ptr_conversion<incomplete>();
|
||||
empty_weak_ptr_conversion<int>();
|
||||
empty_weak_ptr_conversion<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
new_weak_ptr_conversion<int>();
|
||||
new_weak_ptr_conversion<X>();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
// main
|
||||
|
||||
int main()
|
||||
@ -1702,18 +2507,25 @@ int main()
|
||||
nullptr_assignment();
|
||||
shared_ptr_copy_assignment();
|
||||
shared_ptr_move_assignment();
|
||||
// unique_ptr_assignment();
|
||||
unique_ptr_assignment();
|
||||
|
||||
default_reset();
|
||||
// pointer_reset();
|
||||
// deleter_reset();
|
||||
// allocator_reset();
|
||||
// aliasing_reset();
|
||||
pointer_reset();
|
||||
deleter_reset();
|
||||
allocator_reset();
|
||||
aliasing_reset();
|
||||
|
||||
// element_access();
|
||||
element_access();
|
||||
shared_ptr_conversion();
|
||||
weak_ptr_conversion();
|
||||
// swap_test();
|
||||
// owner_before_test();
|
||||
// equal_test();
|
||||
// operator< ?
|
||||
// casts
|
||||
// get_pointer
|
||||
// operator<<
|
||||
// hash
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
297
test/make_local_shared_esft_test.cpp
Normal file
297
test/make_local_shared_esft_test.cpp
Normal file
@ -0,0 +1,297 @@
|
||||
// make_local_shared_esft_test.cpp
|
||||
//
|
||||
// Copyright 2007-2009, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/smart_ptr/make_local_shared.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
class X: public boost::enable_shared_from_this<X>
|
||||
{
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
|
||||
public:
|
||||
|
||||
static int instances;
|
||||
|
||||
explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared_noinit< X >();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
235
test/make_local_shared_test.cpp
Normal file
235
test/make_local_shared_test.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
// make_local_shared_test.cpp
|
||||
//
|
||||
// Copyright 2007-2009, 2017 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/smart_ptr/make_local_shared.hpp>
|
||||
#include <boost/smart_ptr/local_shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
class X
|
||||
{
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
|
||||
void * operator new( std::size_t n )
|
||||
{
|
||||
// lack of this definition causes link errors on Comeau C++
|
||||
BOOST_ERROR( "private X::new called" );
|
||||
return ::operator new( n );
|
||||
}
|
||||
|
||||
void operator delete( void * p )
|
||||
{
|
||||
// lack of this definition causes link errors on MSVC
|
||||
BOOST_ERROR( "private X::delete called" );
|
||||
::operator delete( p );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static int instances;
|
||||
|
||||
int v;
|
||||
|
||||
explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::local_shared_ptr< int > pi = boost::make_local_shared< int >();
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( *pi == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< int > pi = boost::make_local_shared_noinit< int >();
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< int > pi = boost::make_local_shared< int >( 5 );
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( *pi == 5 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >();
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 0 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared_noinit< X >();
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 0 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
@ -61,6 +61,28 @@ int main()
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_shared_noinit< X >();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = px->shared_from_this();
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
|
||||
px.reset();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "px->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px = boost::make_shared< X >( 1 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
@ -61,6 +61,12 @@ int main()
|
||||
BOOST_TEST( *pi == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< int > pi = boost::make_shared_noinit< int >();
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< int > pi = boost::make_shared< int >( 5 );
|
||||
|
||||
@ -83,6 +89,19 @@ int main()
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared_noinit< X >();
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 0 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
Reference in New Issue
Block a user