forked from boostorg/smart_ptr
Compare commits
20 Commits
feature/sp
...
feature/de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00f6b5dcb0 | ||
|
|
6195ae1eb0 | ||
|
|
30291c406a | ||
|
|
610f19f247 | ||
|
|
876d40a9ab | ||
|
|
e4d642c46a | ||
|
|
3dffa64f58 | ||
|
|
af92bd89ef | ||
|
|
4742143605 | ||
|
|
872bf10347 | ||
|
|
c0ae9b3728 | ||
|
|
1298c2e8e5 | ||
|
|
d593061b15 | ||
|
|
5072045f12 | ||
|
|
442e179920 | ||
|
|
9544a8cb91 | ||
|
|
5823d6bcc9 | ||
|
|
f56e609757 | ||
|
|
8df63a3d0e | ||
|
|
4b6cb1223b |
33
.travis.yml
33
.travis.yml
@@ -6,6 +6,8 @@ language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
dist: trusty
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
@@ -125,6 +127,26 @@ matrix:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-9
|
||||
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-9
|
||||
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-7
|
||||
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
|
||||
@@ -257,6 +279,17 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-7
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-8
|
||||
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-8
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-7
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
|
||||
|
||||
@@ -33,6 +33,8 @@ include::smart_ptr/make_shared.adoc[]
|
||||
|
||||
include::smart_ptr/enable_shared_from_this.adoc[]
|
||||
|
||||
include::smart_ptr/enable_shared_from.adoc[]
|
||||
|
||||
include::smart_ptr/make_unique.adoc[]
|
||||
|
||||
include::smart_ptr/intrusive_ptr.adoc[]
|
||||
|
||||
@@ -17,3 +17,9 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
* Added aliasing constructors to `weak_ptr`
|
||||
* Added `weak_ptr<T>::empty()`
|
||||
* Added `enable_shared_from`, `shared_from`, and `weak_from`
|
||||
|
||||
## Changes in 1.65.0
|
||||
|
||||
* Added `atomic_shared_ptr`
|
||||
* Added `local_shared_ptr`, `make_local_shared`
|
||||
|
||||
89
doc/smart_ptr/enable_shared_from.adoc
Normal file
89
doc/smart_ptr/enable_shared_from.adoc
Normal file
@@ -0,0 +1,89 @@
|
||||
////
|
||||
Copyright 2002, 2003, 2015, 2017, 2019 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
|
||||
////
|
||||
|
||||
[#enable_shared_from]
|
||||
# enable_shared_from
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix: enable_shared_from_
|
||||
|
||||
## Description
|
||||
|
||||
`enable_shared_from` is used as a base class that allows a `shared_ptr` or a
|
||||
`weak_ptr` to be obtained given a raw pointer to the object, by using the
|
||||
functions `shared_from` and `weak_from`.
|
||||
|
||||
`enable_shared_from` differs from `enable_shared_from_this<T>` by the fact
|
||||
that it's not a template, and is its recommended replacement for new code.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
#include <boost/smart_ptr/enable_shared_from.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <cassert>
|
||||
|
||||
class Y: public boost::enable_shared_from
|
||||
{
|
||||
public:
|
||||
|
||||
boost::shared_ptr<Y> f()
|
||||
{
|
||||
return boost::shared_from( this );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<Y> p(new Y);
|
||||
boost::shared_ptr<Y> q = p->f();
|
||||
assert(p == q);
|
||||
assert(!(p < q || q < p)); // p and q must share ownership
|
||||
}
|
||||
```
|
||||
|
||||
## Synopsis
|
||||
|
||||
`enable_shared_from` is defined in `<boost/smart_ptr/enable_shared_from.hpp>`.
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
class enable_shared_from: public enable_shared_from_this<enable_shared_from>
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> shared_ptr<T> shared_from( T * p );
|
||||
template<class T> weak_ptr<T> weak_from( T * p ) noexcept;
|
||||
}
|
||||
```
|
||||
|
||||
## Functions
|
||||
|
||||
```
|
||||
template<class T> shared_ptr<T> shared_from( T * p );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `shared_ptr<T>( p\->enable_shared_from::shared_from_this(), p )`.
|
||||
|
||||
NOTE: Throws `bad_weak_ptr` when `p` is not owned by a `shared_ptr`.
|
||||
|
||||
```
|
||||
template<class T> weak_ptr<T> weak_from( T * p ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `weak_ptr<T>( p\->enable_shared_from::weak_from_this(), p )`.
|
||||
|
||||
NOTE: Unlike `shared_from(this)`, `weak_from(this)` is valid in a destructor
|
||||
and returns a `weak_ptr` that is `expired()` but still shares ownership
|
||||
with other `weak_ptr` instances (if any) that refer to the object.
|
||||
@@ -142,3 +142,7 @@ template<class T> weak_ptr<T const> weak_from_this() const noexcept;
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `weak_this_`.
|
||||
|
||||
NOTE: Unlike `shared_from_this()`, `weak_from_this()` is valid in a destructor
|
||||
and returns a `weak_ptr` that is `expired()` but still shares ownership
|
||||
with other `weak_ptr` instances (if any) that refer to the object.
|
||||
|
||||
@@ -72,21 +72,19 @@ inline typename enable_if_<is_unbounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
allocate_local_shared(const A& allocator, std::size_t count)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
typedef typename detail::sp_array_element<T>::type element;
|
||||
typedef typename detail::sp_bind_allocator<A, element>::type other;
|
||||
typedef detail::lsp_array_state<other> state;
|
||||
typedef detail::sp_array_base<state> base;
|
||||
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_array_result<other, base> result(allocator, count);
|
||||
base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, size, start);
|
||||
element* start = detail::sp_array_start<element>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, start, count);
|
||||
detail::lsp_array_base& local = node->state().base();
|
||||
local.set(node);
|
||||
result.release();
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), &local);
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
|
||||
&local);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
@@ -94,23 +92,22 @@ inline typename enable_if_<is_bounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
allocate_local_shared(const A& allocator)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
enum {
|
||||
size = detail::sp_array_count<T, scalar>::value
|
||||
count = extent<T>::value
|
||||
};
|
||||
typedef detail::lsp_size_array_state<other, size> state;
|
||||
typedef typename detail::sp_array_element<T>::type element;
|
||||
typedef typename detail::sp_bind_allocator<A, element>::type other;
|
||||
typedef detail::lsp_size_array_state<other, count> state;
|
||||
typedef detail::sp_array_base<state> base;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_array_result<other, base> result(allocator, count);
|
||||
base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, size, start);
|
||||
element* start = detail::sp_array_start<element>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, start, count);
|
||||
detail::lsp_array_base& local = node->state().base();
|
||||
local.set(node);
|
||||
result.release();
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), &local);
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
|
||||
&local);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
@@ -119,25 +116,19 @@ inline typename enable_if_<is_unbounded_array<T>::value,
|
||||
allocate_local_shared(const A& allocator, std::size_t count,
|
||||
const typename remove_extent<T>::type& value)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
typedef typename detail::sp_array_element<T>::type element;
|
||||
typedef typename detail::sp_bind_allocator<A, element>::type other;
|
||||
typedef detail::lsp_array_state<other> state;
|
||||
typedef detail::sp_array_base<state> base;
|
||||
enum {
|
||||
total = detail::sp_array_count<type, scalar>::value
|
||||
};
|
||||
std::size_t size = count * total;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_array_result<other, base> result(allocator, count);
|
||||
base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, size,
|
||||
reinterpret_cast<const scalar*>(&value), total, start);
|
||||
element* start = detail::sp_array_start<element>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, start, count, value);
|
||||
detail::lsp_array_base& local = node->state().base();
|
||||
local.set(node);
|
||||
result.release();
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), &local);
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
|
||||
&local);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
@@ -146,25 +137,22 @@ inline typename enable_if_<is_bounded_array<T>::value,
|
||||
allocate_local_shared(const A& allocator,
|
||||
const typename remove_extent<T>::type& value)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
enum {
|
||||
size = detail::sp_array_count<T, scalar>::value
|
||||
count = extent<T>::value
|
||||
};
|
||||
typedef detail::lsp_size_array_state<other, size> state;
|
||||
typedef typename detail::sp_array_element<T>::type element;
|
||||
typedef typename detail::sp_bind_allocator<A, element>::type other;
|
||||
typedef detail::lsp_size_array_state<other, count> state;
|
||||
typedef detail::sp_array_base<state> base;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_array_result<other, base> result(allocator, count);
|
||||
base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, size,
|
||||
reinterpret_cast<const scalar*>(&value),
|
||||
detail::sp_array_count<type, scalar>::value, start);
|
||||
element* start = detail::sp_array_start<element>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, start, count, value);
|
||||
detail::lsp_array_base& local = node->state().base();
|
||||
local.set(node);
|
||||
result.release();
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), &local);
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
|
||||
&local);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
@@ -172,22 +160,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
allocate_local_shared_noinit(const A& allocator, std::size_t count)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
typedef detail::lsp_array_state<other> state;
|
||||
typedef detail::sp_array_base<state, false> base;
|
||||
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
|
||||
size, start);
|
||||
detail::lsp_array_base& local = node->state().base();
|
||||
local.set(node);
|
||||
result.release();
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), &local);
|
||||
return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator),
|
||||
count);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
@@ -195,24 +169,7 @@ inline typename enable_if_<is_bounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
allocate_local_shared_noinit(const A& allocator)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
enum {
|
||||
size = detail::sp_array_count<T, scalar>::value
|
||||
};
|
||||
typedef detail::lsp_size_array_state<other, size> state;
|
||||
typedef detail::sp_array_base<state, false> base;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
|
||||
size, start);
|
||||
detail::lsp_array_base& local = node->state().base();
|
||||
local.set(node);
|
||||
result.release();
|
||||
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), &local);
|
||||
return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator));
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
@@ -8,15 +8,14 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/core/alloc_construct.hpp>
|
||||
#include <boost/core/first_scalar.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/enable_if.hpp>
|
||||
#include <boost/type_traits/extent.hpp>
|
||||
#include <boost/type_traits/is_bounded_array.hpp>
|
||||
#include <boost/type_traits/is_unbounded_array.hpp>
|
||||
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/type_traits/remove_all_extents.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_extent.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
@@ -25,15 +24,22 @@ namespace boost {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
struct sp_array_scalar {
|
||||
struct sp_array_element {
|
||||
typedef typename boost::remove_cv<typename
|
||||
boost::remove_all_extents<T>::type>::type type;
|
||||
boost::remove_extent<T>::type>::type type;
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
template<class T>
|
||||
struct sp_array_count {
|
||||
enum {
|
||||
value = sizeof(T) / sizeof(U)
|
||||
value = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct sp_array_count<T[N]> {
|
||||
enum {
|
||||
value = N * sp_array_count<T>::value
|
||||
};
|
||||
};
|
||||
|
||||
@@ -70,154 +76,6 @@ sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
|
||||
return (size + sizeof(T) - 1) / sizeof(T);
|
||||
}
|
||||
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<!E &&
|
||||
boost::has_trivial_destructor<T>::value>::type
|
||||
sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
|
||||
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<!E &&
|
||||
!boost::has_trivial_destructor<T>::value>::type
|
||||
sp_array_destroy(A&, T* ptr, std::size_t size)
|
||||
{
|
||||
while (size > 0) {
|
||||
ptr[--size].~T();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<E>::type
|
||||
sp_array_destroy(A& allocator, T* ptr, std::size_t size)
|
||||
{
|
||||
while (size > 0) {
|
||||
std::allocator_traits<A>::destroy(allocator, ptr + --size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<bool E, class A, class T>
|
||||
class sp_destroyer {
|
||||
public:
|
||||
sp_destroyer(A& allocator, T* ptr) BOOST_SP_NOEXCEPT
|
||||
: allocator_(allocator),
|
||||
ptr_(ptr),
|
||||
size_(0) { }
|
||||
|
||||
~sp_destroyer() {
|
||||
sp_array_destroy<E>(allocator_, ptr_, size_);
|
||||
}
|
||||
|
||||
std::size_t& size() BOOST_SP_NOEXCEPT {
|
||||
return size_;
|
||||
}
|
||||
|
||||
private:
|
||||
sp_destroyer(const sp_destroyer&);
|
||||
sp_destroyer& operator=(const sp_destroyer&);
|
||||
|
||||
A& allocator_;
|
||||
T* ptr_;
|
||||
std::size_t size_;
|
||||
};
|
||||
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<!E &&
|
||||
boost::has_trivial_constructor<T>::value &&
|
||||
boost::has_trivial_assign<T>::value &&
|
||||
boost::has_trivial_destructor<T>::value>::type
|
||||
sp_array_construct(A&, T* ptr, std::size_t size)
|
||||
{
|
||||
for (std::size_t i = 0; i < size; ++i) {
|
||||
ptr[i] = T();
|
||||
}
|
||||
}
|
||||
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<!E &&
|
||||
boost::has_trivial_constructor<T>::value &&
|
||||
boost::has_trivial_assign<T>::value &&
|
||||
boost::has_trivial_destructor<T>::value>::type
|
||||
sp_array_construct(A&, T* ptr, std::size_t size, const T* list,
|
||||
std::size_t count)
|
||||
{
|
||||
for (std::size_t i = 0; i < size; ++i) {
|
||||
ptr[i] = list[i % count];
|
||||
}
|
||||
}
|
||||
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<!E &&
|
||||
!(boost::has_trivial_constructor<T>::value &&
|
||||
boost::has_trivial_assign<T>::value &&
|
||||
boost::has_trivial_destructor<T>::value)>::type
|
||||
sp_array_construct(A& none, T* ptr, std::size_t size)
|
||||
{
|
||||
sp_destroyer<E, A, T> hold(none, ptr);
|
||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
||||
::new(static_cast<void*>(ptr + i)) T();
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<!E &&
|
||||
!(boost::has_trivial_constructor<T>::value &&
|
||||
boost::has_trivial_assign<T>::value &&
|
||||
boost::has_trivial_destructor<T>::value)>::type
|
||||
sp_array_construct(A& none, T* ptr, std::size_t size, const T* list,
|
||||
std::size_t count)
|
||||
{
|
||||
sp_destroyer<E, A, T> hold(none, ptr);
|
||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
||||
::new(static_cast<void*>(ptr + i)) T(list[i % count]);
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<E>::type
|
||||
sp_array_construct(A& allocator, T* ptr, std::size_t size)
|
||||
{
|
||||
sp_destroyer<E, A, T> hold(allocator, ptr);
|
||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
||||
std::allocator_traits<A>::construct(allocator, ptr + i);
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
|
||||
template<bool E, class A, class T>
|
||||
inline typename boost::enable_if_<E>::type
|
||||
sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
|
||||
std::size_t count)
|
||||
{
|
||||
sp_destroyer<E, A, T> hold(allocator, ptr);
|
||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
||||
std::allocator_traits<A>::construct(allocator, ptr + i,
|
||||
list[i % count]);
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class A, class T>
|
||||
inline typename
|
||||
boost::enable_if_<boost::has_trivial_constructor<T>::value>::type
|
||||
sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
|
||||
|
||||
template<class A, class T>
|
||||
inline typename
|
||||
boost::enable_if_<!boost::has_trivial_constructor<T>::value>::type
|
||||
sp_array_default(A& none, T* ptr, std::size_t size)
|
||||
{
|
||||
sp_destroyer<false, A, T> hold(none, ptr);
|
||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
||||
::new(static_cast<void*>(ptr + i)) T;
|
||||
}
|
||||
hold.size() = 0;
|
||||
}
|
||||
|
||||
template<class A>
|
||||
class sp_array_state {
|
||||
public:
|
||||
@@ -262,29 +120,6 @@ private:
|
||||
A allocator_;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class A>
|
||||
struct sp_use_construct {
|
||||
enum {
|
||||
value = true
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct sp_use_construct<std::allocator<T> > {
|
||||
enum {
|
||||
value = false
|
||||
};
|
||||
};
|
||||
#else
|
||||
template<class>
|
||||
struct sp_use_construct {
|
||||
enum {
|
||||
value = false
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class T, class U>
|
||||
struct sp_array_alignment {
|
||||
enum {
|
||||
@@ -300,39 +135,32 @@ struct sp_array_offset {
|
||||
};
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
struct sp_array_storage {
|
||||
enum {
|
||||
value = sp_array_alignment<T, U>::value
|
||||
};
|
||||
typedef typename boost::type_with_alignment<value>::type type;
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
template<class U, class T>
|
||||
inline U*
|
||||
sp_array_start(void* base) BOOST_SP_NOEXCEPT
|
||||
sp_array_start(T* base) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
enum {
|
||||
size = sp_array_offset<T, U>::value
|
||||
};
|
||||
return reinterpret_cast<U*>(static_cast<char*>(base) + size);
|
||||
return reinterpret_cast<U*>(reinterpret_cast<char*>(base) + size);
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
class sp_array_creator {
|
||||
typedef typename A::value_type scalar;
|
||||
typedef typename A::value_type element;
|
||||
|
||||
enum {
|
||||
offset = sp_array_offset<T, scalar>::value
|
||||
offset = sp_array_offset<T, element>::value
|
||||
};
|
||||
|
||||
typedef typename sp_array_storage<T, scalar>::type type;
|
||||
typedef typename boost::type_with_alignment<sp_array_alignment<T,
|
||||
element>::value>::type type;
|
||||
|
||||
public:
|
||||
template<class U>
|
||||
sp_array_creator(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
|
||||
: other_(other),
|
||||
size_(sp_objects<type>(offset + sizeof(scalar) * size)) { }
|
||||
size_(sp_objects<type>(offset + sizeof(element) * size)) { }
|
||||
|
||||
T* create() {
|
||||
return reinterpret_cast<T*>(other_.allocate(size_));
|
||||
@@ -347,9 +175,7 @@ private:
|
||||
std::size_t size_;
|
||||
};
|
||||
|
||||
struct sp_default { };
|
||||
|
||||
template<class T, bool E = sp_use_construct<T>::value>
|
||||
template<class T>
|
||||
class BOOST_SYMBOL_VISIBLE sp_array_base
|
||||
: public sp_counted_base {
|
||||
typedef typename T::type allocator;
|
||||
@@ -358,23 +184,22 @@ public:
|
||||
typedef typename allocator::value_type type;
|
||||
|
||||
template<class A>
|
||||
sp_array_base(const A& other, std::size_t size, type* start)
|
||||
sp_array_base(const A& other, type* start, std::size_t size)
|
||||
: state_(other, size) {
|
||||
sp_array_construct<E>(state_.allocator(), start, state_.size());
|
||||
boost::alloc_construct_n(state_.allocator(),
|
||||
boost::first_scalar(start),
|
||||
state_.size() * sp_array_count<type>::value);
|
||||
}
|
||||
|
||||
template<class A>
|
||||
sp_array_base(const A& other, std::size_t size, const type* list,
|
||||
std::size_t count, type* start)
|
||||
template<class A, class U>
|
||||
sp_array_base(const A& other, type* start, std::size_t size, const U& list)
|
||||
: state_(other, size) {
|
||||
sp_array_construct<E>(state_.allocator(), start, state_.size(), list,
|
||||
count);
|
||||
}
|
||||
|
||||
template<class A>
|
||||
sp_array_base(sp_default, const A& other, std::size_t size, type* start)
|
||||
: state_(other, size) {
|
||||
sp_array_default(state_.allocator(), start, state_.size());
|
||||
enum {
|
||||
count = sp_array_count<type>::value
|
||||
};
|
||||
boost::alloc_construct_n(state_.allocator(),
|
||||
boost::first_scalar(start), state_.size() * count,
|
||||
boost::first_scalar(&list), count);
|
||||
}
|
||||
|
||||
T& state() BOOST_SP_NOEXCEPT {
|
||||
@@ -382,8 +207,9 @@ public:
|
||||
}
|
||||
|
||||
virtual void dispose() BOOST_SP_NOEXCEPT {
|
||||
sp_array_destroy<E>(state_.allocator(),
|
||||
sp_array_start<sp_array_base, type>(this), state_.size());
|
||||
boost::alloc_destroy_n(state_.allocator(),
|
||||
boost::first_scalar(sp_array_start<type>(this)),
|
||||
state_.size() * sp_array_count<type>::value);
|
||||
}
|
||||
|
||||
virtual void destroy() BOOST_SP_NOEXCEPT {
|
||||
@@ -423,11 +249,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
T* get() const BOOST_SP_NOEXCEPT {
|
||||
return result_;
|
||||
}
|
||||
|
||||
void release() {
|
||||
void release() BOOST_SP_NOEXCEPT {
|
||||
result_ = 0;
|
||||
}
|
||||
|
||||
@@ -445,40 +271,37 @@ template<class T, class A>
|
||||
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||
allocate_shared(const A& allocator, std::size_t count)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
typedef typename detail::sp_array_element<T>::type element;
|
||||
typedef typename detail::sp_bind_allocator<A, element>::type other;
|
||||
typedef detail::sp_array_state<other> state;
|
||||
typedef detail::sp_array_base<state> base;
|
||||
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_counted_base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, size, start);
|
||||
detail::sp_array_result<other, base> result(allocator, count);
|
||||
base* node = result.get();
|
||||
element* start = detail::sp_array_start<element>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, start, count);
|
||||
result.release();
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), detail::shared_count(node));
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
|
||||
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||
allocate_shared(const A& allocator)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
enum {
|
||||
size = detail::sp_array_count<T, scalar>::value
|
||||
count = extent<T>::value
|
||||
};
|
||||
typedef detail::sp_size_array_state<other, size> state;
|
||||
typedef typename detail::sp_array_element<T>::type element;
|
||||
typedef typename detail::sp_bind_allocator<A, element>::type other;
|
||||
typedef detail::sp_size_array_state<other, extent<T>::value> state;
|
||||
typedef detail::sp_array_base<state> base;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_counted_base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, size, start);
|
||||
detail::sp_array_result<other, base> result(allocator, count);
|
||||
base* node = result.get();
|
||||
element* start = detail::sp_array_start<element>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, start, count);
|
||||
result.release();
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), detail::shared_count(node));
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
|
||||
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
@@ -486,23 +309,17 @@ inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||
allocate_shared(const A& allocator, std::size_t count,
|
||||
const typename remove_extent<T>::type& value)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
typedef typename detail::sp_array_element<T>::type element;
|
||||
typedef typename detail::sp_bind_allocator<A, element>::type other;
|
||||
typedef detail::sp_array_state<other> state;
|
||||
typedef detail::sp_array_base<state> base;
|
||||
enum {
|
||||
total = detail::sp_array_count<type, scalar>::value
|
||||
};
|
||||
std::size_t size = count * total;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_counted_base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, size,
|
||||
reinterpret_cast<const scalar*>(&value), total, start);
|
||||
detail::sp_array_result<other, base> result(allocator, count);
|
||||
base* node = result.get();
|
||||
element* start = detail::sp_array_start<element>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, start, count, value);
|
||||
result.release();
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), detail::shared_count(node));
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
|
||||
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
@@ -510,65 +327,34 @@ inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||
allocate_shared(const A& allocator,
|
||||
const typename remove_extent<T>::type& value)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
enum {
|
||||
size = detail::sp_array_count<T, scalar>::value
|
||||
count = extent<T>::value
|
||||
};
|
||||
typedef detail::sp_size_array_state<other, size> state;
|
||||
typedef typename detail::sp_array_element<T>::type element;
|
||||
typedef typename detail::sp_bind_allocator<A, element>::type other;
|
||||
typedef detail::sp_size_array_state<other, extent<T>::value> state;
|
||||
typedef detail::sp_array_base<state> base;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_counted_base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, size,
|
||||
reinterpret_cast<const scalar*>(&value),
|
||||
detail::sp_array_count<type, scalar>::value, start);
|
||||
detail::sp_array_result<other, base> result(allocator, count);
|
||||
base* node = result.get();
|
||||
element* start = detail::sp_array_start<element>(node);
|
||||
::new(static_cast<void*>(node)) base(allocator, start, count, value);
|
||||
result.release();
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), detail::shared_count(node));
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
|
||||
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||
allocate_shared_noinit(const A& allocator, std::size_t count)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
typedef detail::sp_array_state<other> state;
|
||||
typedef detail::sp_array_base<state, false> base;
|
||||
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_counted_base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
|
||||
size, start);
|
||||
result.release();
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), detail::shared_count(node));
|
||||
return boost::allocate_shared<T>(boost::noinit_adapt(allocator), count);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||
allocate_shared_noinit(const A& allocator)
|
||||
{
|
||||
typedef typename remove_extent<T>::type type;
|
||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||
enum {
|
||||
size = detail::sp_array_count<T, scalar>::value
|
||||
};
|
||||
typedef detail::sp_size_array_state<other, size> state;
|
||||
typedef detail::sp_array_base<state, false> base;
|
||||
detail::sp_array_result<other, base> result(allocator, size);
|
||||
detail::sp_counted_base* node = result.get();
|
||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
|
||||
size, start);
|
||||
result.release();
|
||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
||||
reinterpret_cast<type*>(start), detail::shared_count(node));
|
||||
return boost::allocate_shared<T>(boost::noinit_adapt(allocator));
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
@@ -26,7 +26,7 @@ class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ): value_( v )
|
||||
explicit atomic_count( long v ): value_( static_cast< std::int_least32_t >( v ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
37
include/boost/smart_ptr/enable_shared_from.hpp
Normal file
37
include/boost/smart_ptr/enable_shared_from.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED
|
||||
|
||||
// enable_shared_from.hpp
|
||||
//
|
||||
// Copyright 2019 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/enable_shared_from_this.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
class enable_shared_from: public enable_shared_from_this<enable_shared_from>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template<class T> shared_ptr<T> shared_from( T * p )
|
||||
{
|
||||
return shared_ptr<T>( p->enable_shared_from::shared_from_this(), p );
|
||||
}
|
||||
|
||||
template<class T> weak_ptr<T> weak_from( T * p ) BOOST_SP_NOEXCEPT
|
||||
{
|
||||
return weak_ptr<T>( p->enable_shared_from::weak_from_this(), p );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED
|
||||
@@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/core/default_allocator.hpp>
|
||||
#include <boost/smart_ptr/allocate_local_shared_array.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -18,8 +19,8 @@ inline typename enable_if_<is_bounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
make_local_shared()
|
||||
{
|
||||
return boost::allocate_local_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>());
|
||||
return boost::allocate_local_shared<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -27,8 +28,8 @@ inline typename enable_if_<is_bounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
make_local_shared(const typename remove_extent<T>::type& value)
|
||||
{
|
||||
return boost::allocate_local_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), value);
|
||||
return boost::allocate_local_shared<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>(), value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -36,8 +37,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
make_local_shared(std::size_t size)
|
||||
{
|
||||
return boost::allocate_local_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size);
|
||||
return boost::allocate_local_shared<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>(), size);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -46,8 +47,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
|
||||
make_local_shared(std::size_t size,
|
||||
const typename remove_extent<T>::type& value)
|
||||
{
|
||||
return boost::allocate_local_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size, value);
|
||||
return boost::allocate_local_shared<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>(), size, value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -55,8 +56,8 @@ inline typename enable_if_<is_bounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
make_local_shared_noinit()
|
||||
{
|
||||
return boost::allocate_local_shared_noinit<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>());
|
||||
return boost::allocate_local_shared_noinit<T>(boost::
|
||||
default_allocator<typename detail::sp_array_element<T>::type>());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -64,8 +65,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
|
||||
local_shared_ptr<T> >::type
|
||||
make_local_shared_noinit(std::size_t size)
|
||||
{
|
||||
return boost::allocate_local_shared_noinit<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size);
|
||||
return boost::allocate_local_shared_noinit<T>(boost::
|
||||
default_allocator<typename detail::sp_array_element<T>::type>(), size);
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
@@ -8,6 +8,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/core/default_allocator.hpp>
|
||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -16,48 +17,48 @@ template<class T>
|
||||
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||
make_shared()
|
||||
{
|
||||
return boost::allocate_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>());
|
||||
return boost::allocate_shared<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||
make_shared(const typename remove_extent<T>::type& value)
|
||||
{
|
||||
return boost::allocate_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), value);
|
||||
return boost::allocate_shared<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>(), value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||
make_shared(std::size_t size)
|
||||
{
|
||||
return boost::allocate_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size);
|
||||
return boost::allocate_shared<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>(), size);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||
make_shared(std::size_t size, const typename remove_extent<T>::type& value)
|
||||
{
|
||||
return boost::allocate_shared<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size, value);
|
||||
return boost::allocate_shared<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>(), size, value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||
make_shared_noinit()
|
||||
{
|
||||
return boost::allocate_shared_noinit<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>());
|
||||
return boost::allocate_shared_noinit<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||
make_shared_noinit(std::size_t size)
|
||||
{
|
||||
return boost::allocate_shared_noinit<T>(std::allocator<typename
|
||||
detail::sp_array_scalar<T>::type>(), size);
|
||||
return boost::allocate_shared_noinit<T>(boost::default_allocator<typename
|
||||
detail::sp_array_element<T>::type>(), size);
|
||||
}
|
||||
|
||||
} /* boost */
|
||||
|
||||
@@ -315,3 +315,7 @@ run sp_typeinfo_test.cpp : : : <rtti>off : sp_typeinfo_test_no_rtti ;
|
||||
run get_deleter_test.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test_no_rtti ;
|
||||
run get_deleter_test2.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test2_no_rtti ;
|
||||
run get_deleter_test3.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test3_no_rtti ;
|
||||
|
||||
run shared_from_test.cpp ;
|
||||
run weak_from_test.cpp ;
|
||||
run weak_from_test2.cpp ;
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ > 4
|
||||
# pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||
#endif
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
|
||||
102
test/shared_from_test.cpp
Normal file
102
test/shared_from_test.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
|
||||
// shared_from_test.cpp
|
||||
//
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
class X
|
||||
{
|
||||
private:
|
||||
|
||||
int m_;
|
||||
|
||||
public:
|
||||
|
||||
X(): m_() {}
|
||||
};
|
||||
|
||||
class Y: public boost::enable_shared_from
|
||||
{
|
||||
};
|
||||
|
||||
class Z: public X, public Y
|
||||
{
|
||||
public:
|
||||
|
||||
boost::shared_ptr<Z> shared_from_this()
|
||||
{
|
||||
return boost::shared_from( this );
|
||||
}
|
||||
};
|
||||
|
||||
void null_deleter( void const* )
|
||||
{
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<Z> p( new Z );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr<Z> q = p->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( p, q );
|
||||
BOOST_TEST( !( p < q ) && !( q < p ) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const & )
|
||||
{
|
||||
BOOST_ERROR( "p->shared_from_this() failed" );
|
||||
}
|
||||
|
||||
Z v2( *p );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr<Z> q = v2.shared_from_this();
|
||||
BOOST_ERROR( "v2.shared_from_this() failed to throw" );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const & )
|
||||
{
|
||||
}
|
||||
|
||||
*p = Z();
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr<Z> q = p->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( p, q );
|
||||
BOOST_TEST( !( p < q ) && !( q < p ) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const & )
|
||||
{
|
||||
BOOST_ERROR( "p->shared_from_this() threw bad_weak_ptr after *p = Z()" );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr<Z> p2( p.get(), null_deleter );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr<Z> q = p->shared_from_this();
|
||||
|
||||
BOOST_TEST_EQ( p, q );
|
||||
BOOST_TEST( !( p < q ) && !( q < p ) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "p->shared_from_this() failed" );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -7,6 +7,10 @@
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ > 4
|
||||
# pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_from_this_test.cpp
|
||||
//
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ > 4
|
||||
# pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_ptr_basic_test.cpp
|
||||
//
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ > 4
|
||||
# pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_ptr_test.cpp
|
||||
//
|
||||
|
||||
97
test/weak_from_test.cpp
Normal file
97
test/weak_from_test.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
// weak_from_test.cpp
|
||||
//
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
class X
|
||||
{
|
||||
private:
|
||||
|
||||
int m_;
|
||||
|
||||
public:
|
||||
|
||||
X(): m_() {}
|
||||
};
|
||||
|
||||
class Y: public boost::enable_shared_from
|
||||
{
|
||||
};
|
||||
|
||||
class Z: public X, public Y
|
||||
{
|
||||
public:
|
||||
|
||||
boost::weak_ptr<Z> weak_from_this()
|
||||
{
|
||||
return boost::weak_from( this );
|
||||
}
|
||||
};
|
||||
|
||||
void null_deleter( void const* )
|
||||
{
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<Z> sp( new Z );
|
||||
boost::weak_ptr<Z> p( sp );
|
||||
|
||||
{
|
||||
boost::weak_ptr<Z> q = sp->weak_from_this();
|
||||
|
||||
BOOST_TEST_EQ( p.lock(), q.lock() );
|
||||
BOOST_TEST( !( p < q ) && !( q < p ) );
|
||||
}
|
||||
|
||||
Z v2( *sp );
|
||||
|
||||
{
|
||||
boost::weak_ptr<Z> q = v2.weak_from_this();
|
||||
BOOST_TEST( q.expired() );
|
||||
}
|
||||
|
||||
*sp = Z();
|
||||
|
||||
{
|
||||
boost::weak_ptr<Z> q = sp->weak_from_this();
|
||||
|
||||
BOOST_TEST_EQ( p.lock(), q.lock() );
|
||||
BOOST_TEST( !( p < q ) && !( q < p ) );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr<Z> sp2( sp.get(), null_deleter );
|
||||
}
|
||||
|
||||
{
|
||||
boost::weak_ptr<Z> q = sp->weak_from_this();
|
||||
|
||||
BOOST_TEST_EQ( p.lock(), q.lock() );
|
||||
BOOST_TEST( !( p < q ) && !( q < p ) );
|
||||
}
|
||||
|
||||
{
|
||||
boost::weak_ptr<Z> p2 = sp->weak_from_this();
|
||||
|
||||
BOOST_TEST( !p.expired() );
|
||||
BOOST_TEST( !p2.expired() );
|
||||
|
||||
sp.reset();
|
||||
|
||||
BOOST_TEST( p.expired() );
|
||||
BOOST_TEST( p2.expired() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
57
test/weak_from_test2.cpp
Normal file
57
test/weak_from_test2.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
// weak_from_test2.cpp
|
||||
//
|
||||
// Tests weak_from in a destructor
|
||||
//
|
||||
// Copyright 2014, 2015, 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
class X: public boost::enable_shared_from
|
||||
{
|
||||
private:
|
||||
|
||||
boost::weak_ptr<X> px_;
|
||||
|
||||
public:
|
||||
|
||||
X()
|
||||
{
|
||||
boost::weak_ptr<X> p1 = weak_from( this );
|
||||
BOOST_TEST( p1._empty() );
|
||||
BOOST_TEST( p1.expired() );
|
||||
}
|
||||
|
||||
void check()
|
||||
{
|
||||
boost::weak_ptr<X> p2 = weak_from( this );
|
||||
BOOST_TEST( !p2.expired() );
|
||||
|
||||
BOOST_TEST( p2.lock().get() == this );
|
||||
|
||||
px_ = p2;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
boost::weak_ptr<X> p3 = weak_from( this );
|
||||
BOOST_TEST( p3.expired() );
|
||||
|
||||
BOOST_TEST( !(px_ < p3) && !(p3 < px_) );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::shared_ptr< X > px( new X );
|
||||
px->check();
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -39,7 +39,7 @@ void test()
|
||||
|
||||
*p = V();
|
||||
|
||||
boost::weak_ptr<V> q4 = p->shared_from_this();
|
||||
boost::weak_ptr<V> q4 = p->weak_from_this();
|
||||
BOOST_TEST( !q4.expired() );
|
||||
BOOST_TEST( !(q < q4) && !(q4 < q) );
|
||||
BOOST_TEST( !(q2 < q4) && !(q4 < q2) );
|
||||
|
||||
Reference in New Issue
Block a user