summaryrefslogtreecommitdiff
path: root/boost/smart_ptr
diff options
context:
space:
mode:
Diffstat (limited to 'boost/smart_ptr')
-rw-r--r--boost/smart_ptr/allocate_local_shared_array.hpp228
-rw-r--r--boost/smart_ptr/allocate_shared_array.hpp983
-rw-r--r--boost/smart_ptr/atomic_shared_ptr.hpp183
-rw-r--r--boost/smart_ptr/bad_weak_ptr.hpp6
-rw-r--r--boost/smart_ptr/detail/atomic_count_gcc.hpp2
-rw-r--r--boost/smart_ptr/detail/local_counted_base.hpp146
-rw-r--r--boost/smart_ptr/detail/local_sp_deleter.hpp91
-rw-r--r--boost/smart_ptr/detail/lwm_win32_cs.hpp28
-rw-r--r--boost/smart_ptr/detail/operator_bool.hpp12
-rw-r--r--boost/smart_ptr/detail/shared_count.hpp18
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_aix.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_clang.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_nt.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_pt.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_solaris.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_spin.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_sync.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_base_w32.hpp1
-rw-r--r--boost/smart_ptr/detail/sp_counted_impl.hpp29
-rw-r--r--boost/smart_ptr/detail/sp_noexcept.hpp24
-rw-r--r--boost/smart_ptr/detail/yield_k.hpp2
-rw-r--r--boost/smart_ptr/enable_shared_from_this.hpp12
-rw-r--r--boost/smart_ptr/intrusive_ptr.hpp52
-rw-r--r--boost/smart_ptr/intrusive_ref_counter.hpp33
-rw-r--r--boost/smart_ptr/local_shared_ptr.hpp684
-rw-r--r--boost/smart_ptr/make_local_shared.hpp17
-rw-r--r--boost/smart_ptr/make_local_shared_array.hpp67
-rw-r--r--boost/smart_ptr/make_local_shared_object.hpp199
-rw-r--r--boost/smart_ptr/make_shared.hpp3
-rw-r--r--boost/smart_ptr/make_shared_object.hpp38
-rw-r--r--boost/smart_ptr/owner_less.hpp2
-rw-r--r--boost/smart_ptr/scoped_array.hpp23
-rw-r--r--boost/smart_ptr/scoped_ptr.hpp31
-rw-r--r--boost/smart_ptr/shared_array.hpp44
-rw-r--r--boost/smart_ptr/shared_ptr.hpp225
-rw-r--r--boost/smart_ptr/weak_ptr.hpp46
47 files changed, 2331 insertions, 916 deletions
diff --git a/boost/smart_ptr/allocate_local_shared_array.hpp b/boost/smart_ptr/allocate_local_shared_array.hpp
new file mode 100644
index 0000000000..f46f11049b
--- /dev/null
+++ b/boost/smart_ptr/allocate_local_shared_array.hpp
@@ -0,0 +1,228 @@
+/*
+Copyright 2017 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+Distributed under the Boost Software License, Version 1.0.
+(http://www.boost.org/LICENSE_1_0.txt)
+*/
+#ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
+#define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
+
+#include <boost/smart_ptr/allocate_shared_array.hpp>
+#include <boost/smart_ptr/local_shared_ptr.hpp>
+
+namespace boost {
+namespace detail {
+
+template<class>
+struct lsp_if_array { };
+
+template<class T>
+struct lsp_if_array<T[]> {
+ typedef boost::local_shared_ptr<T[]> type;
+};
+
+template<class>
+struct lsp_if_size_array { };
+
+template<class T, std::size_t N>
+struct lsp_if_size_array<T[N]> {
+ typedef boost::local_shared_ptr<T[N]> type;
+};
+
+class lsp_array_base
+ : public local_counted_base {
+public:
+ void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
+ count_ = shared_count(base);
+ }
+
+ virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
+ shared_count().swap(count_);
+ }
+
+ virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT {
+ return count_;
+ }
+
+private:
+ shared_count count_;
+};
+
+template<class A>
+class lsp_array_state
+ : public sp_array_state<A> {
+public:
+ template<class U>
+ lsp_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
+ : sp_array_state<A>(other, size) { }
+
+ lsp_array_base& base() BOOST_SP_NOEXCEPT {
+ return base_;
+ }
+
+private:
+ lsp_array_base base_;
+};
+
+template<class A, std::size_t N>
+class lsp_size_array_state
+ : public sp_size_array_state<A, N> {
+public:
+ template<class U>
+ lsp_size_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
+ : sp_size_array_state<A, N>(other, size) { }
+
+ lsp_array_base& base() BOOST_SP_NOEXCEPT {
+ return base_;
+ }
+
+private:
+ lsp_array_base base_;
+};
+
+} /* detail */
+
+template<class T, class A>
+inline typename detail::lsp_if_array<T>::type
+allocate_local_shared(const A& allocator, std::size_t count)
+{
+ typedef typename detail::sp_array_element<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> base;
+ std::size_t size = count * detail::sp_array_count<type>::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(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);
+}
+
+template<class T, class A>
+inline typename detail::lsp_if_size_array<T>::type
+allocate_local_shared(const A& allocator)
+{
+ enum {
+ size = detail::sp_array_count<T>::value
+ };
+ typedef typename detail::sp_array_element<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_size_array_state<other, size> state;
+ typedef detail::sp_array_base<state> 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(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);
+}
+
+template<class T, class A>
+inline typename detail::lsp_if_array<T>::type
+allocate_local_shared(const A& allocator, std::size_t count,
+ const typename detail::sp_array_element<T>::type& value)
+{
+ typedef typename detail::sp_array_element<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> base;
+ std::size_t size = count * detail::sp_array_count<type>::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(allocator, size,
+ reinterpret_cast<const scalar*>(&value),
+ detail::sp_array_count<type>::value, 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);
+}
+
+template<class T, class A>
+inline typename detail::lsp_if_size_array<T>::type
+allocate_local_shared(const A& allocator,
+ const typename detail::sp_array_element<T>::type& value)
+{
+ enum {
+ size = detail::sp_array_count<T>::value
+ };
+ typedef typename detail::sp_array_element<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_size_array_state<other, size> state;
+ typedef detail::sp_array_base<state> 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(allocator, size,
+ reinterpret_cast<const scalar*>(&value),
+ detail::sp_array_count<type>::value, 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);
+}
+
+template<class T, class A>
+inline typename detail::lsp_if_array<T>::type
+allocate_local_shared_noinit(const A& allocator, std::size_t count)
+{
+ typedef typename detail::sp_array_element<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>::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);
+}
+
+template<class T, class A>
+inline typename detail::lsp_if_size_array<T>::type
+allocate_local_shared_noinit(const A& allocator)
+{
+ enum {
+ size = detail::sp_array_count<T>::value
+ };
+ typedef typename detail::sp_array_element<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_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);
+}
+
+} /* boost */
+
+#endif
diff --git a/boost/smart_ptr/allocate_shared_array.hpp b/boost/smart_ptr/allocate_shared_array.hpp
index b43b43d575..23c35aff3f 100644
--- a/boost/smart_ptr/allocate_shared_array.hpp
+++ b/boost/smart_ptr/allocate_shared_array.hpp
@@ -9,9 +9,10 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/type_traits/alignment_of.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/alignment_of.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
namespace boost {
@@ -105,37 +106,24 @@ struct sp_array_count<T[N]> {
};
};
-template<class T>
-struct sp_array_count<T[]> { };
-
-template<class D, class T>
-inline D*
-sp_get_deleter(const
- boost::shared_ptr<T>& value) BOOST_NOEXCEPT_OR_NOTHROW
-{
- return static_cast<D*>(value._internal_get_untyped_deleter());
-}
-
-template<std::size_t N, std::size_t A>
-struct sp_array_storage {
- union type {
- char value[N];
- typename boost::type_with_alignment<A>::type other;
+template<std::size_t N, std::size_t M>
+struct sp_max_size {
+ enum {
+ value = N < M ? M : N
};
};
template<std::size_t N, std::size_t M>
-struct sp_max_size {
+struct sp_align_up {
enum {
- value = N < M ? M : N
+ value = (N + M - 1) & ~(M - 1)
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
struct sp_bind_allocator {
- typedef typename std::allocator_traits<A>::template
- rebind_alloc<T> type;
+ typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
};
#else
template<class A, class T>
@@ -144,6 +132,13 @@ struct sp_bind_allocator {
};
#endif
+template<class T>
+BOOST_CONSTEXPR inline std::size_t
+sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
+{
+ return (size + sizeof(T) - 1) / sizeof(T);
+}
+
template<bool, class = void>
struct sp_enable { };
@@ -152,873 +147,549 @@ struct sp_enable<true, T> {
typedef T type;
};
-template<class T>
-inline
-typename sp_enable<boost::has_trivial_destructor<T>::value>::type
-sp_array_destroy(T*, std::size_t) BOOST_NOEXCEPT { }
+template<bool E, class A, class T>
+inline typename sp_enable<!E && boost::has_trivial_destructor<T>::value>::type
+sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
-template<class T>
-inline
-typename sp_enable<!boost::has_trivial_destructor<T>::value>::type
-sp_array_destroy(T* storage, std::size_t size)
+template<bool E, class A, class T>
+inline typename sp_enable<!E &&
+ !boost::has_trivial_destructor<T>::value>::type
+sp_array_destroy(A&, T* start, std::size_t size)
{
while (size > 0) {
- storage[--size].~T();
+ start[--size].~T();
}
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
-template<class A, class T>
-inline void
-sp_array_destroy(A& allocator, T* storage, std::size_t size)
+template<bool E, class A, class T>
+inline typename sp_enable<E>::type
+sp_array_destroy(A& allocator, T* start, std::size_t size)
{
while (size > 0) {
- std::allocator_traits<A>::destroy(allocator, &storage[--size]);
+ std::allocator_traits<A>::destroy(allocator, start + --size);
}
}
#endif
-#if !defined(BOOST_NO_EXCEPTIONS)
-template<class T>
-inline
-typename sp_enable<boost::has_trivial_constructor<T>::value ||
- boost::has_trivial_destructor<T>::value>::type
-sp_array_construct(T* storage, std::size_t size)
+template<bool E, class A, class T>
+inline typename sp_enable<!E &&
+ boost::has_trivial_constructor<T>::value &&
+ boost::has_trivial_assign<T>::value>::type
+sp_array_construct(A&, T* start, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
- ::new(static_cast<void*>(storage + i)) T();
+ start[i] = T();
}
}
-template<class T>
-inline
-typename sp_enable<!boost::has_trivial_constructor<T>::value &&
- !boost::has_trivial_destructor<T>::value>::type
-sp_array_construct(T* storage, std::size_t size)
+template<bool E, class A, class T>
+inline typename sp_enable<!E &&
+ boost::has_trivial_constructor<T>::value &&
+ boost::has_trivial_assign<T>::value>::type
+sp_array_construct(A&, T* start, std::size_t size, const T* list,
+ std::size_t count)
+{
+ for (std::size_t i = 0; i < size; ++i) {
+ start[i] = list[i % count];
+ }
+}
+
+#if !defined(BOOST_NO_EXCEPTIONS)
+template<bool E, class A, class T>
+inline typename sp_enable<!E &&
+ !(boost::has_trivial_constructor<T>::value &&
+ boost::has_trivial_assign<T>::value)>::type
+sp_array_construct(A& none, T* start, std::size_t size)
{
std::size_t i = 0;
try {
for (; i < size; ++i) {
- ::new(static_cast<void*>(storage + i)) T();
+ ::new(static_cast<void*>(start + i)) T();
}
} catch (...) {
- while (i > 0) {
- storage[--i].~T();
- }
+ sp_array_destroy<E>(none, start, i);
throw;
}
}
-template<class T>
-inline void
-sp_array_construct(T* storage, std::size_t size, const T* list,
+template<bool E, class A, class T>
+inline typename sp_enable<!E &&
+ !(boost::has_trivial_constructor<T>::value &&
+ boost::has_trivial_assign<T>::value)>::type
+sp_array_construct(A& none, T* start, std::size_t size, const T* list,
std::size_t count)
{
std::size_t i = 0;
try {
for (; i < size; ++i) {
- ::new(static_cast<void*>(storage + i)) T(list[i % count]);
+ ::new(static_cast<void*>(start + i)) T(list[i % count]);
}
} catch (...) {
- while (i > 0) {
- storage[--i].~T();
- }
+ sp_array_destroy<E>(none, start, i);
throw;
}
}
#else
-template<class T>
-inline void
-sp_array_construct(T* storage, std::size_t size)
+template<bool E, class A, class T>
+inline typename sp_enable<!E &&
+ !(boost::has_trivial_constructor<T>::value &&
+ boost::has_trivial_assign<T>::value)>::type
+sp_array_construct(A&, T* start, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
- ::new(static_cast<void*>(storage + i)) T();
+ ::new(static_cast<void*>(start + i)) T();
}
}
-template<class T>
-inline void
-sp_array_construct(T* storage, std::size_t size, const T* list,
+template<bool E, class A, class T>
+inline typename sp_enable<!E &&
+ !(boost::has_trivial_constructor<T>::value &&
+ boost::has_trivial_assign<T>::value)>::type
+sp_array_construct(A&, T* start, std::size_t size, const T* list,
std::size_t count)
{
for (std::size_t i = 0; i < size; ++i) {
- ::new(static_cast<void*>(storage + i)) T(list[i % count]);
+ ::new(static_cast<void*>(start + i)) T(list[i % count]);
}
}
#endif
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#if !defined(BOOST_NO_EXCEPTIONS)
-template<class A, class T>
-inline void
-sp_array_construct(A& allocator, T* storage, std::size_t size)
+template<bool E, class A, class T>
+inline typename sp_enable<E>::type
+sp_array_construct(A& allocator, T* start, std::size_t size)
{
std::size_t i = 0;
try {
for (i = 0; i < size; ++i) {
- std::allocator_traits<A>::construct(allocator, storage + i);
+ std::allocator_traits<A>::construct(allocator, start + i);
}
} catch (...) {
- sp_array_destroy(allocator, storage, i);
+ sp_array_destroy<E>(allocator, start, i);
throw;
}
}
-template<class A, class T>
-inline void
-sp_array_construct(A& allocator, T* storage, std::size_t size,
- const T* list, std::size_t count)
+template<bool E, class A, class T>
+inline typename sp_enable<E>::type
+sp_array_construct(A& allocator, T* start, std::size_t size, const T* list,
+ std::size_t count)
{
std::size_t i = 0;
try {
for (i = 0; i < size; ++i) {
- std::allocator_traits<A>::construct(allocator, storage + i,
+ std::allocator_traits<A>::construct(allocator, start + i,
list[i % count]);
}
} catch (...) {
- sp_array_destroy(allocator, storage, i);
+ sp_array_destroy<E>(allocator, start, i);
throw;
}
}
#else
-template<class A, class T>
-inline void
-sp_array_construct(A& allocator, T* storage, std::size_t size)
+template<bool E, class A, class T>
+inline typename sp_enable<E>::type
+sp_array_construct(A& allocator, T* start, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
- std::allocator_traits<A>::construct(allocator, storage + i);
+ std::allocator_traits<A>::construct(allocator, start + i);
}
}
-template<class A, class T>
-inline void
-sp_array_construct(A& allocator, T* storage, std::size_t size,
- const T* list, std::size_t count)
+template<bool E, class A, class T>
+inline typename sp_enable<E>::type
+sp_array_construct(A& allocator, T* start, std::size_t size, const T* list,
+ std::size_t count)
{
for (std::size_t i = 0; i < size; ++i) {
- std::allocator_traits<A>::construct(allocator, storage + i,
+ std::allocator_traits<A>::construct(allocator, start + i,
list[i % count]);
}
}
#endif
#endif
-template<class T>
-inline
-typename sp_enable<boost::has_trivial_constructor<T>::value>::type
-sp_array_default(T*, std::size_t) BOOST_NOEXCEPT { }
+template<class A, class T>
+inline typename sp_enable<boost::has_trivial_constructor<T>::value>::type
+sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
#if !defined(BOOST_NO_EXCEPTIONS)
-template<class T>
-inline
-typename sp_enable<!boost::has_trivial_constructor<T>::value &&
- boost::has_trivial_destructor<T>::value>::type
-sp_array_default(T* storage, std::size_t size)
-{
- for (std::size_t i = 0; i < size; ++i) {
- ::new(static_cast<void*>(storage + i)) T;
- }
-}
-
-template<class T>
-inline
-typename sp_enable<!boost::has_trivial_constructor<T>::value &&
- !boost::has_trivial_destructor<T>::value>::type
-sp_array_default(T* storage, std::size_t size)
+template<class A, class T>
+inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type
+sp_array_default(A& none, T* start, std::size_t size)
{
std::size_t i = 0;
try {
for (; i < size; ++i) {
- ::new(static_cast<void*>(storage + i)) T;
+ ::new(static_cast<void*>(start + i)) T;
}
} catch (...) {
- while (i > 0) {
- storage[--i].~T();
- }
+ sp_array_destroy<false>(none, start, i);
throw;
}
}
#else
-template<class T>
-inline
-typename sp_enable<!boost::has_trivial_constructor<T>::value>::type
-sp_array_default(T* storage, std::size_t size)
+template<bool E, class A, class T>
+inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type
+sp_array_default(A&, T* start, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
- ::new(static_cast<void*>(storage + i)) T;
+ ::new(static_cast<void*>(start + i)) T;
}
}
#endif
-template<class T, std::size_t N>
-struct sp_less_align {
- enum {
- value = (boost::alignment_of<T>::value) < N
- };
-};
-
-template<class T, std::size_t N>
-BOOST_CONSTEXPR inline
-typename sp_enable<sp_less_align<T, N>::value, std::size_t>::type
-sp_align(std::size_t size) BOOST_NOEXCEPT
-{
- return (sizeof(T) * size + N - 1) & ~(N - 1);
-}
-
-template<class T, std::size_t N>
-BOOST_CONSTEXPR inline
-typename sp_enable<!sp_less_align<T, N>::value, std::size_t>::type
-sp_align(std::size_t size) BOOST_NOEXCEPT
-{
- return sizeof(T) * size;
-}
-
-template<class T>
-BOOST_CONSTEXPR inline std::size_t
-sp_types(std::size_t size) BOOST_NOEXCEPT
-{
- return (size + sizeof(T) - 1) / sizeof(T);
-}
-
-template<class T, std::size_t N>
-class sp_size_array_deleter {
-public:
- template<class U>
- static void operator_fn(U) BOOST_NOEXCEPT { }
-
- sp_size_array_deleter() BOOST_NOEXCEPT
- : enabled_(false) { }
-
- template<class A>
- sp_size_array_deleter(const A&) BOOST_NOEXCEPT
- : enabled_(false) { }
-
- sp_size_array_deleter(const sp_size_array_deleter&) BOOST_NOEXCEPT
- : enabled_(false) { }
-
- ~sp_size_array_deleter() {
- if (enabled_) {
- sp_array_destroy(reinterpret_cast<T*>(&storage_), N);
- }
- }
-
- template<class U>
- void operator()(U) {
- if (enabled_) {
- sp_array_destroy(reinterpret_cast<T*>(&storage_), N);
- enabled_ = false;
- }
- }
-
- void* construct() {
- sp_array_construct(reinterpret_cast<T*>(&storage_), N);
- enabled_ = true;
- return &storage_;
- }
-
- void* construct(const T* list, std::size_t count) {
- sp_array_construct(reinterpret_cast<T*>(&storage_), N,
- list, count);
- enabled_ = true;
- return &storage_;
- }
-
- void* construct_default() {
- sp_array_default(reinterpret_cast<T*>(&storage_), N);
- enabled_ = true;
- return &storage_;
- }
-
-private:
- bool enabled_;
- typename sp_array_storage<sizeof(T) * N,
- boost::alignment_of<T>::value>::type storage_;
-};
-
-#if !defined(BOOST_NO_CXX11_ALLOCATOR)
-template<class T, std::size_t N, class A>
-class sp_size_array_destroyer {
+template<class A>
+class sp_array_state {
public:
- template<class U>
- static void operator_fn(U) BOOST_NOEXCEPT { }
+ typedef A type;
template<class U>
- sp_size_array_destroyer(const U& allocator) BOOST_NOEXCEPT
+ sp_array_state(const U& allocator, std::size_t size) BOOST_SP_NOEXCEPT
: allocator_(allocator),
- enabled_(false) { }
-
- sp_size_array_destroyer(const sp_size_array_destroyer& other)
- BOOST_NOEXCEPT
- : allocator_(other.allocator_),
- enabled_(false) { }
-
- ~sp_size_array_destroyer() {
- if (enabled_) {
- sp_array_destroy(allocator_,
- reinterpret_cast<T*>(&storage_), N);
- }
- }
-
- template<class U>
- void operator()(U) {
- if (enabled_) {
- sp_array_destroy(allocator_,
- reinterpret_cast<T*>(&storage_), N);
- enabled_ = false;
- }
- }
-
- void* construct() {
- sp_array_construct(allocator_,
- reinterpret_cast<T*>(&storage_), N);
- enabled_ = true;
- return &storage_;
- }
-
- void* construct(const T* list, std::size_t count) {
- sp_array_construct(allocator_,
- reinterpret_cast<T*>(&storage_), N, list, count);
- enabled_ = true;
- return &storage_;
- }
-
- const A& allocator() const BOOST_NOEXCEPT {
- return allocator_;
- }
-
-private:
- typename sp_array_storage<sizeof(T) * N,
- boost::alignment_of<T>::value>::type storage_;
- A allocator_;
- bool enabled_;
-};
-#endif
-
-template<class T>
-class sp_array_deleter {
-public:
- template<class U>
- static void operator_fn(U) BOOST_NOEXCEPT { }
-
- sp_array_deleter(std::size_t size) BOOST_NOEXCEPT
- : address_(0),
size_(size) { }
- template<class A>
- sp_array_deleter(const A& allocator) BOOST_NOEXCEPT
- : address_(0),
- size_(allocator.size()) { }
-
- template<class A>
- sp_array_deleter(const A&, std::size_t size) BOOST_NOEXCEPT
- : address_(0),
- size_(size) { }
-
- sp_array_deleter(const sp_array_deleter& other) BOOST_NOEXCEPT
- : address_(0),
- size_(other.size_) { }
-
- ~sp_array_deleter() {
- if (address_) {
- sp_array_destroy(static_cast<T*>(address_), size_);
- }
- }
-
- template<class U>
- void operator()(U) {
- if (address_) {
- sp_array_destroy(static_cast<T*>(address_), size_);
- address_ = 0;
- }
- }
-
- void construct(T* address) {
- sp_array_construct(address, size_);
- address_ = address;
- }
-
- void construct(T* address, const T* list, std::size_t count) {
- sp_array_construct(address, size_, list, count);
- address_ = address;
- }
-
- void construct_default(T* address) {
- sp_array_default(address, size_);
- address_ = address;
- }
-
- std::size_t size() const BOOST_NOEXCEPT {
- return size_;
- }
-
-private:
- void* address_;
- std::size_t size_;
-};
-
-#if !defined(BOOST_NO_CXX11_ALLOCATOR)
-template<class T, class A>
-class sp_array_destroyer {
-public:
- template<class U>
- static void operator_fn(U) BOOST_NOEXCEPT { }
-
- template<class U>
- sp_array_destroyer(const U& allocator, std::size_t size)
- BOOST_NOEXCEPT
- : allocator_(allocator),
- size_(size),
- address_(0) { }
-
- template<class U>
- sp_array_destroyer(const U& allocator) BOOST_NOEXCEPT
- : allocator_(allocator.allocator()),
- size_(allocator.size()),
- address_(0) { }
-
- sp_array_destroyer(const sp_array_destroyer& other) BOOST_NOEXCEPT
- : allocator_(other.allocator_),
- size_(other.size_),
- address_(0) { }
-
- ~sp_array_destroyer() {
- if (address_) {
- sp_array_destroy(allocator_, static_cast<T*>(address_),
- size_);
- }
- }
-
- template<class U>
- void operator()(U) {
- if (address_) {
- sp_array_destroy(allocator_, static_cast<T*>(address_),
- size_);
- address_ = 0;
- }
- }
-
- void construct(T* address) {
- sp_array_construct(allocator_, address, size_);
- address_ = address;
- }
-
- void construct(T* address, const T* list, std::size_t count) {
- sp_array_construct(allocator_, address, size_, list, count);
- address_ = address;
- }
-
- const A& allocator() const BOOST_NOEXCEPT {
+ A& allocator() BOOST_SP_NOEXCEPT {
return allocator_;
}
- std::size_t size() const BOOST_NOEXCEPT {
+ std::size_t size() const BOOST_SP_NOEXCEPT {
return size_;
}
private:
A allocator_;
std::size_t size_;
- void* address_;
};
-#endif
-
-template<class T, class A>
-class sp_array_allocator {
- template<class U, class V>
- friend class sp_array_allocator;
+template<class A, std::size_t N>
+class sp_size_array_state {
public:
- typedef typename A::value_type value_type;
-
-private:
- enum {
- alignment = sp_max_size<boost::alignment_of<T>::value,
- boost::alignment_of<value_type>::value>::value
- };
-
- typedef typename boost::type_with_alignment<alignment>::type type;
- typedef typename sp_bind_allocator<A, type>::type type_allocator;
-
-public:
- template<class U>
- struct rebind {
- typedef sp_array_allocator<T,
- typename sp_bind_allocator<A, U>::type> other;
- };
-
- sp_array_allocator(const A& allocator, std::size_t size,
- void** result) BOOST_NOEXCEPT
- : allocator_(allocator),
- size_(size),
- result_(result) { }
-
- sp_array_allocator(const A& allocator, std::size_t size)
- BOOST_NOEXCEPT
- : allocator_(allocator),
- size_(size) { }
+ typedef A type;
template<class U>
- sp_array_allocator(const sp_array_allocator<T, U>& other)
- BOOST_NOEXCEPT
- : allocator_(other.allocator_),
- size_(other.size_),
- result_(other.result_) { }
-
- value_type* allocate(std::size_t count) {
- type_allocator allocator(allocator_);
- std::size_t node = sp_align<value_type, alignment>(count);
- std::size_t size = sp_types<type>(node + sizeof(T) * size_);
- type* address = allocator.allocate(size);
- *result_ = reinterpret_cast<char*>(address) + node;
- return reinterpret_cast<value_type*>(address);
- }
+ sp_size_array_state(const U& allocator, std::size_t) BOOST_SP_NOEXCEPT
+ : allocator_(allocator) { }
- void deallocate(value_type* value, std::size_t count) {
- type_allocator allocator(allocator_);
- std::size_t node = sp_align<value_type, alignment>(count);
- std::size_t size = sp_types<type>(node + sizeof(T) * size_);
- allocator.deallocate(reinterpret_cast<type*>(value), size);
- }
-
- const A& allocator() const BOOST_NOEXCEPT {
+ A& allocator() BOOST_SP_NOEXCEPT {
return allocator_;
}
- std::size_t size() const BOOST_NOEXCEPT {
- return size_;
+ BOOST_CONSTEXPR std::size_t size() const BOOST_SP_NOEXCEPT {
+ return N;
}
private:
A allocator_;
- std::size_t size_;
- void** result_;
};
-template<class T, class U, class V>
-inline bool
-operator==(const sp_array_allocator<T, U>& first,
- const sp_array_allocator<T, V>& second) BOOST_NOEXCEPT
-{
- return first.allocator() == second.allocator() &&
- first.size() == second.size();
-}
-
-template<class T, class U, class V>
-inline bool
-operator!=(const sp_array_allocator<T, U>& first,
- const sp_array_allocator<T, V>& second) BOOST_NOEXCEPT
-{
- return !(first == second);
-}
-
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
-template<class A, class T, std::size_t N>
-struct sp_select_size_deleter {
- typedef sp_size_array_destroyer<T, N,
- typename sp_bind_allocator<A, T>::type> type;
+template<class A>
+struct sp_use_construct {
+ enum {
+ value = true
+ };
};
-template<class U, class T, std::size_t N>
-struct sp_select_size_deleter<std::allocator<U>, T, N> {
- typedef sp_size_array_deleter<T, N> type;
+template<class T>
+struct sp_use_construct<std::allocator<T> > {
+ enum {
+ value = false
+ };
};
-
-template<class A, class T>
-struct sp_select_deleter {
- typedef sp_array_destroyer<T,
- typename sp_bind_allocator<A, T>::type> type;
+#else
+template<class>
+struct sp_use_construct {
+ enum {
+ value = false
+ };
};
+#endif
-template<class U, class T>
-struct sp_select_deleter<std::allocator<U>, T> {
- typedef sp_array_deleter<T> type;
-};
-#else
-template<class, class T, std::size_t N>
-struct sp_select_size_deleter {
- typedef sp_size_array_deleter<T, N> type;
+template<class T, class U>
+struct sp_array_alignment {
+ enum {
+ value = sp_max_size<boost::alignment_of<T>::value,
+ boost::alignment_of<U>::value>::value
+ };
};
-template<class, class T>
-struct sp_select_deleter {
- typedef sp_array_deleter<T> type;
+template<class T, class U>
+struct sp_array_offset {
+ enum {
+ value = sp_align_up<sizeof(T), sp_array_alignment<T, U>::value>::value
+ };
};
-#endif
-template<class P, class T, std::size_t N, class A>
-class sp_counted_impl_pda<P, sp_size_array_deleter<T, N>, A>
- : public sp_counted_base {
-public:
- typedef sp_size_array_deleter<T, N> deleter_type;
+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;
+};
-private:
- typedef sp_counted_impl_pda<P, deleter_type, A> type;
- typedef typename sp_bind_allocator<A, type>::type deallocator;
+template<class T, class U>
+inline U*
+sp_array_start(void* base) BOOST_SP_NOEXCEPT
+{
+ enum {
+ size = sp_array_offset<T, U>::value
+ };
+ return reinterpret_cast<U*>(static_cast<char*>(base) + size);
+}
-public:
- sp_counted_impl_pda(P, const deleter_type&, const A& allocator)
- : deleter_(allocator),
- allocator_(allocator) { }
+template<class A, class T>
+class sp_array_creator {
+ typedef typename A::value_type scalar;
- sp_counted_impl_pda(P, const A& allocator)
- : deleter_(allocator) { }
+ enum {
+ offset = sp_array_offset<T, scalar>::value
+ };
- void dispose() {
- deleter_(0);
- }
+ typedef typename sp_array_storage<T, scalar>::type type;
- void destroy() {
- deallocator allocator(allocator_);
- this->~type();
- allocator.deallocate(this, 1);
- }
+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)) { }
- void* get_deleter(const sp_typeinfo&) {
- return &reinterpret_cast<char&>(deleter_);
+ T* create() {
+ return reinterpret_cast<T*>(other_.allocate(size_));
}
- void* get_untyped_deleter() {
- return &reinterpret_cast<char&>(deleter_);
+ void destroy(T* base) {
+ other_.deallocate(reinterpret_cast<type*>(base), size_);
}
private:
- deleter_type deleter_;
- A allocator_;
+ typename sp_bind_allocator<A, type>::type other_;
+ std::size_t size_;
};
-#if !defined(BOOST_NO_CXX11_ALLOCATOR)
-template<class P, class T, std::size_t N, class U, class A>
-class sp_counted_impl_pda<P, sp_size_array_destroyer<T, N, U>, A>
- : public sp_counted_base {
-public:
- typedef sp_size_array_destroyer<T, N, U> deleter_type;
+struct sp_default { };
-private:
- typedef sp_counted_impl_pda<P, deleter_type, A> type;
- typedef typename sp_bind_allocator<A, type>::type deallocator;
+template<class T, bool E = sp_use_construct<T>::value>
+class sp_array_base
+ : public sp_counted_base {
+ typedef typename T::type allocator;
public:
- sp_counted_impl_pda(P, const deleter_type&, const A& allocator)
- : deleter_(allocator) { }
-
- sp_counted_impl_pda(P, const A& allocator)
- : deleter_(allocator) { }
+ typedef typename allocator::value_type type;
- void dispose() {
- deleter_(0);
+ template<class A>
+ sp_array_base(const A& other, std::size_t size, type* start)
+ : state_(other, size) {
+ sp_array_construct<E>(state_.allocator(), start, state_.size());
}
- void destroy() {
- deallocator allocator(deleter_.allocator());
- this->~type();
- allocator.deallocate(this, 1);
+ template<class A>
+ sp_array_base(const A& other, std::size_t size, const type* list,
+ std::size_t count, type* start)
+ : state_(other, size) {
+ sp_array_construct<E>(state_.allocator(), start, state_.size(), list,
+ count);
}
- void* get_deleter(const sp_typeinfo&) {
- return &reinterpret_cast<char&>(deleter_);
+ 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());
}
- void* get_untyped_deleter() {
- return &reinterpret_cast<char&>(deleter_);
+ T& state() BOOST_SP_NOEXCEPT {
+ return state_;
}
-private:
- deleter_type deleter_;
-};
-#endif
-
-template<class P, class T, class A>
-class sp_counted_impl_pda<P, sp_array_deleter<T>,
- sp_array_allocator<T, A> >
- : public sp_counted_base {
-public:
- typedef sp_array_deleter<T> deleter_type;
- typedef sp_array_allocator<T, A> allocator_type;
-
-private:
- typedef sp_counted_impl_pda<P, deleter_type, allocator_type> type;
- typedef sp_array_allocator<T,
- typename sp_bind_allocator<A, type>::type> deallocator;
-
-public:
- sp_counted_impl_pda(P, const deleter_type&,
- const allocator_type& allocator)
- : deleter_(allocator),
- allocator_(allocator.allocator()) { }
-
- sp_counted_impl_pda(P, const allocator_type& allocator)
- : deleter_(allocator),
- allocator_(allocator.allocator()) { }
+ virtual void dispose() {
+ sp_array_destroy<E>(state_.allocator(),
+ sp_array_start<sp_array_base, type>(this), state_.size());
+ }
- void dispose() {
- deleter_(0);
+ virtual void destroy() {
+ sp_array_creator<allocator, sp_array_base> other(state_.allocator(),
+ state_.size());
+ this->~sp_array_base();
+ other.destroy(this);
}
- void destroy() {
- deallocator allocator(allocator_, deleter_.size());
- this->~type();
- allocator.deallocate(this, 1);
+ virtual void* get_deleter(const sp_typeinfo&) {
+ return 0;
}
- void* get_deleter(const sp_typeinfo&) {
- return &reinterpret_cast<char&>(deleter_);
+ virtual void* get_local_deleter(const sp_typeinfo&) {
+ return 0;
}
- void* get_untyped_deleter() {
- return &reinterpret_cast<char&>(deleter_);
+ virtual void* get_untyped_deleter() {
+ return 0;
}
private:
- deleter_type deleter_;
- A allocator_;
+ T state_;
};
-#if !defined(BOOST_NO_CXX11_ALLOCATOR)
-template<class P, class T, class U, class A>
-class sp_counted_impl_pda<P, sp_array_destroyer<T, U>,
- sp_array_allocator<T, A> >
- : public sp_counted_base {
-public:
- typedef sp_array_destroyer<T, U> deleter_type;
- typedef sp_array_allocator<T, A> allocator_type;
-
-private:
- typedef sp_counted_impl_pda<P, deleter_type, allocator_type> type;
- typedef sp_array_allocator<T,
- typename sp_bind_allocator<A, type>::type> deallocator;
-
+template<class A, class T>
+struct sp_array_result {
public:
- sp_counted_impl_pda(P, const deleter_type&,
- const allocator_type& allocator)
- : deleter_(allocator) { }
-
- sp_counted_impl_pda(P, const allocator_type& allocator)
- : deleter_(allocator) { }
-
- void dispose() {
- deleter_(0);
- }
+ template<class U>
+ sp_array_result(const U& other, std::size_t size)
+ : creator_(other, size),
+ result_(creator_.create()) { }
- void destroy() {
- deallocator allocator(deleter_.allocator(), deleter_.size());
- this->~type();
- allocator.deallocate(this, 1);
+ ~sp_array_result() {
+ if (result_) {
+ creator_.destroy(result_);
+ }
}
- void* get_deleter(const sp_typeinfo&) {
- return &reinterpret_cast<char&>(deleter_);
+ T* get() const {
+ return result_;
}
- void* get_untyped_deleter() {
- return &reinterpret_cast<char&>(deleter_);
+ void release() {
+ result_ = 0;
}
private:
- deleter_type deleter_;
+ sp_array_result(const sp_array_result&);
+ sp_array_result& operator=(const sp_array_result&);
+
+ sp_array_creator<A, T> creator_;
+ T* result_;
};
-#endif
} /* detail */
template<class T, class A>
-inline typename detail::sp_if_size_array<T>::type
-allocate_shared(const A& allocator)
+inline typename detail::sp_if_array<T>::type
+allocate_shared(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
- typedef typename detail::sp_select_size_deleter<A, scalar,
- detail::sp_array_count<T>::value>::type deleter;
- shared_ptr<T> result(static_cast<type*>(0),
- detail::sp_inplace_tag<deleter>(), allocator);
- deleter* state = detail::sp_get_deleter<deleter>(result);
- void* start = state->construct();
- return shared_ptr<T>(result, static_cast<type*>(start));
+ typedef typename detail::sp_bind_allocator<A, scalar>::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>::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);
+ result.release();
+ return shared_ptr<T>(detail::sp_internal_constructor_tag(),
+ reinterpret_cast<type*>(start), detail::shared_count(node));
}
template<class T, class A>
inline typename detail::sp_if_size_array<T>::type
-allocate_shared(const A& allocator,
- const typename detail::sp_array_element<T>::type& value)
+allocate_shared(const A& allocator)
{
+ enum {
+ size = detail::sp_array_count<T>::value
+ };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
- typedef typename detail::sp_select_size_deleter<A, scalar,
- detail::sp_array_count<T>::value>::type deleter;
- shared_ptr<T> result(static_cast<type*>(0),
- detail::sp_inplace_tag<deleter>(), allocator);
- deleter* state = detail::sp_get_deleter<deleter>(result);
- void* start = state->construct(reinterpret_cast<const
- scalar*>(&value), detail::sp_array_count<type>::value);
- return shared_ptr<T>(result, static_cast<type*>(start));
+ typedef typename detail::sp_bind_allocator<A, scalar>::type other;
+ typedef detail::sp_size_array_state<other, size> 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);
+ result.release();
+ return shared_ptr<T>(detail::sp_internal_constructor_tag(),
+ reinterpret_cast<type*>(start), detail::shared_count(node));
}
template<class T, class A>
-inline typename detail::sp_if_size_array<T>::type
-allocate_shared_noinit(const A& allocator)
+inline typename detail::sp_if_array<T>::type
+allocate_shared(const A& allocator, std::size_t count,
+ const typename detail::sp_array_element<T>::type& value)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
- typedef detail::sp_size_array_deleter<scalar,
- detail::sp_array_count<T>::value> deleter;
- shared_ptr<T> result(static_cast<type*>(0),
- detail::sp_inplace_tag<deleter>(), allocator);
- deleter* state = detail::sp_get_deleter<deleter>(result);
- void* start = state->construct_default();
- return shared_ptr<T>(result, static_cast<type*>(start));
+ typedef typename detail::sp_bind_allocator<A, scalar>::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>::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,
+ reinterpret_cast<const scalar*>(&value),
+ detail::sp_array_count<type>::value, start);
+ result.release();
+ return shared_ptr<T>(detail::sp_internal_constructor_tag(),
+ reinterpret_cast<type*>(start), detail::shared_count(node));
}
template<class T, class A>
-inline typename detail::sp_if_array<T>::type
-allocate_shared(const A& allocator, std::size_t count)
+inline typename detail::sp_if_size_array<T>::type
+allocate_shared(const A& allocator,
+ const typename detail::sp_array_element<T>::type& value)
{
+ enum {
+ size = detail::sp_array_count<T>::value
+ };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
- typedef typename detail::sp_select_deleter<A, scalar>::type deleter;
- std::size_t size = count * detail::sp_array_count<type>::value;
- void* start;
- shared_ptr<T> result(static_cast<type*>(0),
- detail::sp_inplace_tag<deleter>(),
- detail::sp_array_allocator<scalar, A>(allocator, size, &start));
- deleter* state = detail::sp_get_deleter<deleter>(result);
- state->construct(static_cast<scalar*>(start));
- return shared_ptr<T>(result, static_cast<type*>(start));
+ typedef typename detail::sp_bind_allocator<A, scalar>::type other;
+ typedef detail::sp_size_array_state<other, size> 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>::value, start);
+ result.release();
+ return shared_ptr<T>(detail::sp_internal_constructor_tag(),
+ reinterpret_cast<type*>(start), detail::shared_count(node));
}
template<class T, class A>
inline typename detail::sp_if_array<T>::type
-allocate_shared(const A& allocator, std::size_t count,
- const typename detail::sp_array_element<T>::type& value)
+allocate_shared_noinit(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
- typedef typename detail::sp_select_deleter<A, scalar>::type deleter;
+ 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>::value;
- void* start;
- shared_ptr<T> result(static_cast<type*>(0),
- detail::sp_inplace_tag<deleter>(),
- detail::sp_array_allocator<scalar, A>(allocator, size, &start));
- deleter* state = detail::sp_get_deleter<deleter>(result);
- state->construct(static_cast<scalar*>(start),
- reinterpret_cast<const scalar*>(&value),
- detail::sp_array_count<type>::value);
- return shared_ptr<T>(result, static_cast<type*>(start));
+ 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));
}
template<class T, class A>
-inline typename detail::sp_if_array<T>::type
-allocate_shared_noinit(const A& allocator, std::size_t count)
+inline typename detail::sp_if_size_array<T>::type
+allocate_shared_noinit(const A& allocator)
{
+ enum {
+ size = detail::sp_array_count<T>::value
+ };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
- typedef detail::sp_array_deleter<scalar> deleter;
- std::size_t size = count * detail::sp_array_count<type>::value;
- void* start;
- shared_ptr<T> result(static_cast<type*>(0),
- detail::sp_inplace_tag<deleter>(),
- detail::sp_array_allocator<scalar, A>(allocator, size, &start));
- deleter* state = detail::sp_get_deleter<deleter>(result);
- state->construct_default(static_cast<scalar*>(start));
- return shared_ptr<T>(result, static_cast<type*>(start));
+ typedef typename detail::sp_bind_allocator<A, scalar>::type other;
+ 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));
}
} /* boost */
diff --git a/boost/smart_ptr/atomic_shared_ptr.hpp b/boost/smart_ptr/atomic_shared_ptr.hpp
new file mode 100644
index 0000000000..d1efa8e280
--- /dev/null
+++ b/boost/smart_ptr/atomic_shared_ptr.hpp
@@ -0,0 +1,183 @@
+#ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
+#define BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
+
+//
+// atomic_shared_ptr.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/shared_ptr.hpp>
+#include <boost/smart_ptr/detail/spinlock.hpp>
+#include <cstring>
+
+namespace boost
+{
+
+template<class T> class atomic_shared_ptr
+{
+private:
+
+ boost::shared_ptr<T> p_;
+
+ mutable boost::detail::spinlock l_;
+
+ atomic_shared_ptr(const atomic_shared_ptr&);
+ atomic_shared_ptr& operator=(const atomic_shared_ptr&);
+
+private:
+
+ bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
+ {
+ l_.lock();
+
+ if( p_._internal_equiv( v ) )
+ {
+ p_.swap( w );
+
+ l_.unlock();
+ return true;
+ }
+ else
+ {
+ shared_ptr<T> tmp( p_ );
+
+ l_.unlock();
+
+ tmp.swap( v );
+ return false;
+ }
+ }
+
+public:
+
+#if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR )
+
+ constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT
+ {
+ }
+
+#else
+
+ atomic_shared_ptr() BOOST_SP_NOEXCEPT
+ {
+ boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
+ std::memcpy( &l_, &init, sizeof( init ) );
+ }
+
+#endif
+
+ atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+ : p_( std::move( p ) )
+#else
+ : p_( p )
+#endif
+ {
+ boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
+ std::memcpy( &l_, &init, sizeof( init ) );
+ }
+
+ atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
+ {
+ boost::detail::spinlock::scoped_lock lock( l_ );
+ p_.swap( r );
+
+ return *this;
+ }
+
+ BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT
+ {
+ return false;
+ }
+
+ shared_ptr<T> load( int = 0 ) const BOOST_SP_NOEXCEPT
+ {
+ boost::detail::spinlock::scoped_lock lock( l_ );
+ return p_;
+ }
+
+ operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
+ {
+ boost::detail::spinlock::scoped_lock lock( l_ );
+ return p_;
+ }
+
+ void store( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT
+ {
+ boost::detail::spinlock::scoped_lock lock( l_ );
+ p_.swap( r );
+ }
+
+ shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT
+ {
+ {
+ boost::detail::spinlock::scoped_lock lock( l_ );
+ p_.swap( r );
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ return std::move( r );
+
+#else
+
+ return r;
+
+#endif
+ }
+
+ bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT
+ {
+ return compare_exchange( v, w );
+ }
+
+ bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT
+ {
+ return compare_exchange( v, w );
+ }
+
+ bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT
+ {
+ return compare_exchange( v, w );
+ }
+
+ bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT
+ {
+ return compare_exchange( v, w );
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) BOOST_SP_NOEXCEPT
+ {
+ return compare_exchange( v, std::move( w ) );
+ }
+
+ bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT
+ {
+ return compare_exchange( v, std::move( w ) );
+ }
+
+ bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) BOOST_SP_NOEXCEPT
+ {
+ return compare_exchange( v, std::move( w ) );
+ }
+
+ bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT
+ {
+ return compare_exchange( v, std::move( w ) );
+ }
+
+#endif
+};
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
diff --git a/boost/smart_ptr/bad_weak_ptr.hpp b/boost/smart_ptr/bad_weak_ptr.hpp
index 582fad8b71..b086be595f 100644
--- a/boost/smart_ptr/bad_weak_ptr.hpp
+++ b/boost/smart_ptr/bad_weak_ptr.hpp
@@ -17,6 +17,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
+#include <boost/config.hpp>
#include <exception>
#ifdef __BORLANDC__
@@ -36,7 +37,8 @@ namespace boost
# pragma option push -pc
#endif
-#if defined(__clang__)
+#if defined(BOOST_CLANG)
+// Intel C++ on Mac defines __clang__ but doesn't support the pragma
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wweak-vtables"
#endif
@@ -51,7 +53,7 @@ public:
}
};
-#if defined(__clang__)
+#if defined(BOOST_CLANG)
# pragma clang diagnostic pop
#endif
diff --git a/boost/smart_ptr/detail/atomic_count_gcc.hpp b/boost/smart_ptr/detail/atomic_count_gcc.hpp
index 54807e944e..df7e32365f 100644
--- a/boost/smart_ptr/detail/atomic_count_gcc.hpp
+++ b/boost/smart_ptr/detail/atomic_count_gcc.hpp
@@ -9,7 +9,7 @@
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
-// Copyright (c) 2002 Lars Gullik Bjønnes <larsbj@lyx.org>
+// Copyright (c) 2002 Lars Gullik Bjønnes <larsbj@lyx.org>
// Copyright 2003-2005 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
diff --git a/boost/smart_ptr/detail/local_counted_base.hpp b/boost/smart_ptr/detail/local_counted_base.hpp
new file mode 100644
index 0000000000..398b46dd1a
--- /dev/null
+++ b/boost/smart_ptr/detail/local_counted_base.hpp
@@ -0,0 +1,146 @@
+#ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/local_counted_base.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/shared_count.hpp>
+#include <boost/config.hpp>
+#include <utility>
+
+namespace boost
+{
+
+namespace detail
+{
+
+class local_counted_base
+{
+private:
+
+ local_counted_base & operator= ( local_counted_base const & );
+
+private:
+
+ // not 'int' or 'unsigned' to avoid aliasing and enable optimizations
+ enum count_type { min_ = 0, initial_ = 1, max_ = 2147483647 };
+
+ count_type local_use_count_;
+
+public:
+
+ BOOST_CONSTEXPR local_counted_base() BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
+ {
+ }
+
+ BOOST_CONSTEXPR local_counted_base( local_counted_base const & ) BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
+ {
+ }
+
+ virtual ~local_counted_base() /*BOOST_SP_NOEXCEPT*/
+ {
+ }
+
+ virtual void local_cb_destroy() 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
+ {
+#if defined( __has_builtin )
+# if __has_builtin( __builtin_assume )
+
+ __builtin_assume( local_use_count_ >= 1 );
+
+# endif
+#endif
+
+ local_use_count_ = static_cast<count_type>( local_use_count_ + 1 );
+ }
+
+ void release() BOOST_SP_NOEXCEPT
+ {
+ local_use_count_ = static_cast<count_type>( local_use_count_ - 1 );
+
+ if( local_use_count_ == 0 )
+ {
+ local_cb_destroy();
+ }
+ }
+
+ long local_use_count() const BOOST_SP_NOEXCEPT
+ {
+ return local_use_count_;
+ }
+};
+
+class local_counted_impl: public local_counted_base
+{
+private:
+
+ local_counted_impl( local_counted_impl const & );
+
+private:
+
+ shared_count pn_;
+
+public:
+
+ explicit local_counted_impl( shared_count const& pn ): pn_( pn )
+ {
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) )
+ {
+ }
+
+#endif
+
+ virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
+ {
+ delete this;
+ }
+
+ virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
+ {
+ return pn_;
+ }
+};
+
+class local_counted_impl_em: public local_counted_base
+{
+public:
+
+ shared_count pn_;
+
+ virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
+ {
+ shared_count().swap( pn_ );
+ }
+
+ virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
+ {
+ return pn_;
+ }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED
diff --git a/boost/smart_ptr/detail/local_sp_deleter.hpp b/boost/smart_ptr/detail/local_sp_deleter.hpp
new file mode 100644
index 0000000000..7d04f1dc52
--- /dev/null
+++ b/boost/smart_ptr/detail/local_sp_deleter.hpp
@@ -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
diff --git a/boost/smart_ptr/detail/lwm_win32_cs.hpp b/boost/smart_ptr/detail/lwm_win32_cs.hpp
index a93cf09208..7d3e156166 100644
--- a/boost/smart_ptr/detail/lwm_win32_cs.hpp
+++ b/boost/smart_ptr/detail/lwm_win32_cs.hpp
@@ -21,7 +21,13 @@
#include <boost/predef.h>
#ifdef BOOST_USE_WINDOWS_H
-# include <windows.h>
+
+#include <windows.h>
+
+#else
+
+struct _RTL_CRITICAL_SECTION;
+
#endif
namespace boost
@@ -47,13 +53,13 @@ struct critical_section
};
#if BOOST_PLAT_WINDOWS_RUNTIME
-extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(critical_section *, unsigned long, unsigned long);
+extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long);
#else
-extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *);
#endif
-extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
-extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
-extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *);
+extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *);
+extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *);
#else
@@ -75,15 +81,15 @@ public:
lightweight_mutex()
{
#if BOOST_PLAT_WINDOWS_RUNTIME
- InitializeCriticalSectionEx(&cs_, 4000, 0);
+ boost::detail::InitializeCriticalSectionEx(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_), 4000, 0);
#else
- InitializeCriticalSection(&cs_);
+ boost::detail::InitializeCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_));
#endif
}
~lightweight_mutex()
{
- DeleteCriticalSection(&cs_);
+ boost::detail::DeleteCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_));
}
class scoped_lock;
@@ -102,12 +108,12 @@ public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
- EnterCriticalSection(&m_.cs_);
+ boost::detail::EnterCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_.cs_));
}
~scoped_lock()
{
- LeaveCriticalSection(&m_.cs_);
+ boost::detail::LeaveCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_.cs_));
}
};
};
diff --git a/boost/smart_ptr/detail/operator_bool.hpp b/boost/smart_ptr/detail/operator_bool.hpp
index c0289b870b..f9c5ef6803 100644
--- a/boost/smart_ptr/detail/operator_bool.hpp
+++ b/boost/smart_ptr/detail/operator_bool.hpp
@@ -9,14 +9,14 @@
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )\
&& !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
- explicit operator bool () const BOOST_NOEXCEPT
+ explicit operator bool () const BOOST_SP_NOEXCEPT
{
return px != 0;
}
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
- operator bool () const BOOST_NOEXCEPT
+ operator bool () const BOOST_SP_NOEXCEPT
{
return px != 0;
}
@@ -29,7 +29,7 @@
typedef void (*unspecified_bool_type)( this_type*** );
- operator unspecified_bool_type() const BOOST_NOEXCEPT
+ operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: unspecified_bool;
}
@@ -41,7 +41,7 @@
typedef element_type * (this_type::*unspecified_bool_type)() const;
- operator unspecified_bool_type() const BOOST_NOEXCEPT
+ operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: &this_type::get;
}
@@ -50,7 +50,7 @@
typedef element_type * this_type::*unspecified_bool_type;
- operator unspecified_bool_type() const BOOST_NOEXCEPT
+ operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: &this_type::px;
}
@@ -58,7 +58,7 @@
#endif
// operator! is redundant, but some compilers need it
- bool operator! () const BOOST_NOEXCEPT
+ bool operator! () const BOOST_SP_NOEXCEPT
{
return px == 0;
}
diff --git a/boost/smart_ptr/detail/shared_count.hpp b/boost/smart_ptr/detail/shared_count.hpp
index 9813842300..ae7d0fb46f 100644
--- a/boost/smart_ptr/detail/shared_count.hpp
+++ b/boost/smart_ptr/detail/shared_count.hpp
@@ -54,7 +54,7 @@ namespace boost
namespace movelib
{
- template< class T, class D > class unique_ptr;
+template< class T, class D > class unique_ptr;
} // namespace movelib
@@ -118,7 +118,14 @@ private:
public:
- shared_count(): pi_(0) // nothrow
+ BOOST_CONSTEXPR shared_count(): pi_(0) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ }
+
+ BOOST_CONSTEXPR explicit shared_count( sp_counted_base * pi ): pi_( pi ) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
@@ -496,6 +503,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;
@@ -517,7 +529,7 @@ private:
public:
- weak_count(): pi_(0) // nothrow
+ BOOST_CONSTEXPR weak_count(): pi_(0) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
diff --git a/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
index cebc243d2e..ec6f6ee184 100644
--- a/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/boost/smart_ptr/detail/sp_counted_base_aix.hpp
index fe6c727e38..ce8ee686ba 100644
--- a/boost/smart_ptr/detail/sp_counted_base_aix.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_aix.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_clang.hpp b/boost/smart_ptr/detail/sp_counted_base_clang.hpp
index 75984959d3..8b3bfad9b6 100644
--- a/boost/smart_ptr/detail/sp_counted_base_clang.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_clang.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
index 6c268e8921..065f7c3d14 100644
--- a/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
index 81eba6f178..3a3d4d4119 100644
--- a/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
index f6e3904157..6c3cce8d44 100644
--- a/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
index 545c8ae4fc..76ac2a612d 100644
--- a/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
index 2e5bc0e853..0fb807488a 100644
--- a/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
index c6d20ce7ea..b8bb707f1b 100644
--- a/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
index 173dce5c81..3d2dd61ed6 100644
--- a/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/boost/smart_ptr/detail/sp_counted_base_nt.hpp
index 5c901f9d16..dea905c905 100644
--- a/boost/smart_ptr/detail/sp_counted_base_nt.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_nt.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/boost/smart_ptr/detail/sp_counted_base_pt.hpp
index a16d2d8652..85f2563d5d 100644
--- a/boost/smart_ptr/detail/sp_counted_base_pt.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_pt.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
index 56ed79fa97..7b5f9178a6 100644
--- a/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_solaris.hpp b/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
index 0e05fef4cb..0db9c6cbd5 100644
--- a/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/boost/smart_ptr/detail/sp_counted_base_spin.hpp
index 77734e727d..faf503ad57 100644
--- a/boost/smart_ptr/detail/sp_counted_base_spin.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_spin.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp b/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
index cab8453591..7a188f8a66 100644
--- a/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/boost/smart_ptr/detail/sp_counted_base_sync.hpp
index fafed0e72e..d2138e7c26 100644
--- a/boost/smart_ptr/detail/sp_counted_base_sync.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_sync.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
index 162f309b56..f2de3b02d8 100644
--- a/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/boost/smart_ptr/detail/sp_counted_base_w32.hpp
index 4ba509c6cd..960e42e128 100644
--- a/boost/smart_ptr/detail/sp_counted_base_w32.hpp
+++ b/boost/smart_ptr/detail/sp_counted_base_w32.hpp
@@ -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()
diff --git a/boost/smart_ptr/detail/sp_counted_impl.hpp b/boost/smart_ptr/detail/sp_counted_impl.hpp
index b29769e3af..fa2f75eb1a 100644
--- a/boost/smart_ptr/detail/sp_counted_impl.hpp
+++ b/boost/smart_ptr/detail/sp_counted_impl.hpp
@@ -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_ );
diff --git a/boost/smart_ptr/detail/sp_noexcept.hpp b/boost/smart_ptr/detail/sp_noexcept.hpp
index 6818dce38d..1287ba4952 100644
--- a/boost/smart_ptr/detail/sp_noexcept.hpp
+++ b/boost/smart_ptr/detail/sp_noexcept.hpp
@@ -9,7 +9,7 @@
// detail/sp_noexcept.hpp
//
-// Copyright 2016 Peter Dimov
+// Copyright 2016, 2017 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
@@ -17,13 +17,31 @@
#include <boost/config.hpp>
+// BOOST_SP_NOEXCEPT
+
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1700 && BOOST_MSVC < 1900
-#define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW
+# define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW
+
+#else
+
+# define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT
+
+#endif
+
+// BOOST_SP_NOEXCEPT_WITH_ASSERT
+
+#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) )
+
+# define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_NOEXCEPT
+
+#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) )
+
+# define BOOST_SP_NOEXCEPT_WITH_ASSERT
#else
-#define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT
+# define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_NOEXCEPT
#endif
diff --git a/boost/smart_ptr/detail/yield_k.hpp b/boost/smart_ptr/detail/yield_k.hpp
index 44d1836478..f8ca6b6467 100644
--- a/boost/smart_ptr/detail/yield_k.hpp
+++ b/boost/smart_ptr/detail/yield_k.hpp
@@ -33,7 +33,7 @@
// BOOST_SMT_PAUSE
-#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
+#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) && !defined(__c2__)
extern "C" void _mm_pause();
diff --git a/boost/smart_ptr/enable_shared_from_this.hpp b/boost/smart_ptr/enable_shared_from_this.hpp
index 642403a0a3..fc4de0b571 100644
--- a/boost/smart_ptr/enable_shared_from_this.hpp
+++ b/boost/smart_ptr/enable_shared_from_this.hpp
@@ -10,7 +10,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
-// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/smart_ptr/weak_ptr.hpp>
@@ -26,11 +26,11 @@ template<class T> class enable_shared_from_this
{
protected:
- enable_shared_from_this() BOOST_SP_NOEXCEPT
+ BOOST_CONSTEXPR enable_shared_from_this() BOOST_SP_NOEXCEPT
{
}
- enable_shared_from_this(enable_shared_from_this const &) BOOST_SP_NOEXCEPT
+ BOOST_CONSTEXPR enable_shared_from_this(enable_shared_from_this const &) BOOST_SP_NOEXCEPT
{
}
@@ -59,12 +59,12 @@ public:
return p;
}
- weak_ptr<T> weak_from_this() BOOST_NOEXCEPT
+ weak_ptr<T> weak_from_this() BOOST_SP_NOEXCEPT
{
return weak_this_;
}
- weak_ptr<T const> weak_from_this() const BOOST_NOEXCEPT
+ weak_ptr<T const> weak_from_this() const BOOST_SP_NOEXCEPT
{
return weak_this_;
}
@@ -72,7 +72,7 @@ public:
public: // actually private, but avoids compiler template friendship issues
// Note: invoked automatically by shared_ptr; do not call
- template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
+ template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const BOOST_SP_NOEXCEPT
{
if( weak_this_.expired() )
{
diff --git a/boost/smart_ptr/intrusive_ptr.hpp b/boost/smart_ptr/intrusive_ptr.hpp
index 0e46212165..0ab075d367 100644
--- a/boost/smart_ptr/intrusive_ptr.hpp
+++ b/boost/smart_ptr/intrusive_ptr.hpp
@@ -6,11 +6,11 @@
//
// Copyright (c) 2001, 2002 Peter Dimov
//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
//
-// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/config.hpp>
@@ -141,7 +141,7 @@ public:
}
template<class U>
- intrusive_ptr & operator=(intrusive_ptr<U> && rhs) BOOST_NOEXCEPT
+ intrusive_ptr & operator=(intrusive_ptr<U> && rhs) BOOST_SP_NOEXCEPT
{
this_type( static_cast< intrusive_ptr<U> && >( rhs ) ).swap(*this);
return *this;
@@ -161,7 +161,7 @@ public:
return *this;
}
- void reset() BOOST_NOEXCEPT
+ void reset()
{
this_type().swap( *this );
}
@@ -176,25 +176,25 @@ public:
this_type( rhs, add_ref ).swap( *this );
}
- T * get() const BOOST_NOEXCEPT
+ T * get() const BOOST_SP_NOEXCEPT
{
return px;
}
- T * detach() BOOST_NOEXCEPT
+ T * detach() BOOST_SP_NOEXCEPT
{
T * ret = px;
px = 0;
return ret;
}
- T & operator*() const
+ T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return *px;
}
- T * operator->() const
+ T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return px;
@@ -203,7 +203,7 @@ public:
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
- void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
+ void swap(intrusive_ptr & rhs) BOOST_SP_NOEXCEPT
{
T * tmp = px;
px = rhs.px;
@@ -215,32 +215,32 @@ private:
T * px;
};
-template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
+template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.get() == b.get();
}
-template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
+template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
-template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
+template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b) BOOST_SP_NOEXCEPT
{
return a.get() == b;
}
-template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
+template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b) BOOST_SP_NOEXCEPT
{
return a.get() != b;
}
-template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
+template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a == b.get();
}
-template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
+template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a != b.get();
}
@@ -249,7 +249,7 @@ template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const
// Resolve the ambiguity between our op!= and the one in rel_ops
-template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
+template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
@@ -258,41 +258,41 @@ template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_p
#if !defined( BOOST_NO_CXX11_NULLPTR )
-template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
-template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
-template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
+template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) BOOST_SP_NOEXCEPT
{
return std::less<T *>()(a.get(), b.get());
}
-template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
+template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) BOOST_SP_NOEXCEPT
{
lhs.swap(rhs);
}
// mem_fn support
-template<class T> T * get_pointer(intrusive_ptr<T> const & p)
+template<class T> T * get_pointer(intrusive_ptr<T> const & p) BOOST_SP_NOEXCEPT
{
return p.get();
}
@@ -351,7 +351,7 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
template< class T > struct hash;
-template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
+template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return boost::hash< T* >()( p.get() );
}
diff --git a/boost/smart_ptr/intrusive_ref_counter.hpp b/boost/smart_ptr/intrusive_ref_counter.hpp
index b7587ea7a0..c2f918d0a4 100644
--- a/boost/smart_ptr/intrusive_ref_counter.hpp
+++ b/boost/smart_ptr/intrusive_ref_counter.hpp
@@ -17,6 +17,7 @@
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
+#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
@@ -45,17 +46,17 @@ struct thread_unsafe_counter
{
typedef unsigned int type;
- static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT
+ static unsigned int load(unsigned int const& counter) BOOST_SP_NOEXCEPT
{
return counter;
}
- static void increment(unsigned int& counter) BOOST_NOEXCEPT
+ static void increment(unsigned int& counter) BOOST_SP_NOEXCEPT
{
++counter;
}
- static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT
+ static unsigned int decrement(unsigned int& counter) BOOST_SP_NOEXCEPT
{
return --counter;
}
@@ -71,17 +72,17 @@ struct thread_safe_counter
{
typedef boost::detail::atomic_count type;
- static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT
+ static unsigned int load(boost::detail::atomic_count const& counter) BOOST_SP_NOEXCEPT
{
return static_cast< unsigned int >(static_cast< long >(counter));
}
- static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
+ static void increment(boost::detail::atomic_count& counter) BOOST_SP_NOEXCEPT
{
++counter;
}
- static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
+ static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_SP_NOEXCEPT
{
return static_cast< unsigned int >(--counter);
}
@@ -91,9 +92,9 @@ template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
class intrusive_ref_counter;
template< typename DerivedT, typename CounterPolicyT >
-void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
+void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT;
template< typename DerivedT, typename CounterPolicyT >
-void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
+void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT;
/*!
* \brief A reference counter base class
@@ -121,7 +122,7 @@ public:
*
* \post <tt>use_count() == 0</tt>
*/
- intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
+ intrusive_ref_counter() BOOST_SP_NOEXCEPT : m_ref_counter(0)
{
}
@@ -130,7 +131,7 @@ public:
*
* \post <tt>use_count() == 0</tt>
*/
- intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
+ intrusive_ref_counter(intrusive_ref_counter const&) BOOST_SP_NOEXCEPT : m_ref_counter(0)
{
}
@@ -139,12 +140,12 @@ public:
*
* \post The reference counter is not modified after assignment
*/
- intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }
+ intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_SP_NOEXCEPT { return *this; }
/*!
* \return The reference counter
*/
- unsigned int use_count() const BOOST_NOEXCEPT
+ unsigned int use_count() const BOOST_SP_NOEXCEPT
{
return CounterPolicyT::load(m_ref_counter);
}
@@ -155,18 +156,18 @@ protected:
*/
BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
- friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
- friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
+ friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT;
+ friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT;
};
template< typename DerivedT, typename CounterPolicyT >
-inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
+inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT
{
CounterPolicyT::increment(p->m_ref_counter);
}
template< typename DerivedT, typename CounterPolicyT >
-inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
+inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_SP_NOEXCEPT
{
if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
delete static_cast< const DerivedT* >(p);
diff --git a/boost/smart_ptr/local_shared_ptr.hpp b/boost/smart_ptr/local_shared_ptr.hpp
new file mode 100644
index 0000000000..0d1fa0182e
--- /dev/null
+++ b/boost/smart_ptr/local_shared_ptr.hpp
@@ -0,0 +1,684 @@
+#ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
+#define BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
+
+// local_shared_ptr.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/shared_ptr.hpp>
+
+namespace boost
+{
+
+template<class T> class local_shared_ptr;
+
+namespace detail
+{
+
+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 >();
+
+ typedef boost::detail::local_sp_deleter< boost::checked_deleter<Y> > D;
+
+ boost::shared_ptr<E> p2( p, D() );
+
+ D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
+
+ 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 )
+{
+ boost::detail::sp_assert_convertible< Y[], E[] >();
+
+ typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
+
+ boost::shared_ptr<E[]> p2( p, D() );
+
+ D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
+
+ 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 )
+{
+ boost::detail::sp_assert_convertible< Y[N], E[N] >();
+
+ typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
+
+ boost::shared_ptr<E[N]> p2( p, D() );
+
+ D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
+
+ 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 )
+{
+ typedef boost::detail::local_sp_deleter<D> D2;
+
+ boost::shared_ptr<E> p2( p, D2( d ) );
+
+ D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
+
+ 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 )
+{
+ typedef boost::detail::local_sp_deleter<D> D2;
+
+ boost::shared_ptr<E> p2( p, D2( d ), a );
+
+ D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
+
+ pd->pn_ = p2._internal_count();
+
+ pn = pd;
+}
+
+struct lsp_internal_constructor_tag
+{
+};
+
+} // namespace detail
+
+//
+// local_shared_ptr
+//
+// as shared_ptr, but local to a thread.
+// reference count manipulations are non-atomic.
+//
+
+template<class T> class local_shared_ptr
+{
+private:
+
+ typedef local_shared_ptr this_type;
+
+public:
+
+ typedef typename boost::detail::sp_element<T>::type element_type;
+
+private:
+
+ element_type * px;
+ boost::detail::local_counted_base * pn;
+
+ template<class Y> friend class local_shared_ptr;
+
+public:
+
+ // destructor
+
+ ~local_shared_ptr() BOOST_SP_NOEXCEPT
+ {
+ if( pn )
+ {
+ pn->release();
+ }
+ }
+
+ // constructors
+
+ BOOST_CONSTEXPR local_shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn( 0 )
+ {
+ }
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ BOOST_CONSTEXPR local_shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn( 0 )
+ {
+ }
+
+#endif
+
+ // internal constructor, used by make_shared
+ BOOST_CONSTEXPR local_shared_ptr( boost::detail::lsp_internal_constructor_tag, element_type * 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 )
+ {
+ boost::detail::lsp_pointer_construct( this, p, pn );
+ }
+
+ template<class Y, class D> local_shared_ptr( Y * p, D d ): px( p ), pn( 0 )
+ {
+ boost::detail::lsp_deleter_construct( this, p, d, pn );
+ }
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ template<class D> local_shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( 0 )
+ {
+ boost::detail::lsp_deleter_construct( this, p, d, pn );
+ }
+
+#endif
+
+ template<class Y, class D, class A> local_shared_ptr( Y * p, D d, A a ): px( p ), pn( 0 )
+ {
+ boost::detail::lsp_allocator_construct( this, p, d, a, pn );
+ }
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ template<class D, class A> local_shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( 0 )
+ {
+ boost::detail::lsp_allocator_construct( this, p, d, a, pn );
+ }
+
+#endif
+
+ // construction from shared_ptr
+
+ template<class Y> local_shared_ptr( shared_ptr<Y> const & r,
+ typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
+ : px( r.get() ), pn( 0 )
+ {
+ boost::detail::sp_assert_convertible< Y, T >();
+
+ if( r.use_count() != 0 )
+ {
+ pn = new boost::detail::local_counted_impl( r._internal_count() );
+ }
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template<class Y> local_shared_ptr( shared_ptr<Y> && r,
+ typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
+ : px( r.get() ), pn( 0 )
+ {
+ boost::detail::sp_assert_convertible< Y, T >();
+
+ if( r.use_count() != 0 )
+ {
+ pn = new boost::detail::local_counted_impl( r._internal_count() );
+ r.reset();
+ }
+ }
+
+#endif
+
+ // construction from unique_ptr
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template< class Y, class D >
+ local_shared_ptr( std::unique_ptr< Y, D > && r,
+ typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
+ : px( r.get() ), pn( 0 )
+ {
+ boost::detail::sp_assert_convertible< Y, T >();
+
+ if( px )
+ {
+ pn = new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) )._internal_count() );
+ }
+ }
+
+#endif
+
+ template< class Y, class D >
+ local_shared_ptr( boost::movelib::unique_ptr< Y, D > r ); // !
+ // : px( r.get() ), pn( new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) ) ) )
+ //{
+ // boost::detail::sp_assert_convertible< Y, T >();
+ //}
+
+ // copy constructor
+
+ local_shared_ptr( local_shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
+ {
+ if( pn )
+ {
+ pn->add_ref();
+ }
+ }
+
+ // move constructor
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ local_shared_ptr( local_shared_ptr && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
+ {
+ r.px = 0;
+ r.pn = 0;
+ }
+
+#endif
+
+ // converting copy constructor
+
+ template<class Y> local_shared_ptr( local_shared_ptr<Y> const & r,
+ typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() ) BOOST_SP_NOEXCEPT
+ : px( r.px ), pn( r.pn )
+ {
+ boost::detail::sp_assert_convertible< Y, T >();
+
+ if( pn )
+ {
+ pn->add_ref();
+ }
+ }
+
+ // converting move constructor
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template<class Y> local_shared_ptr( local_shared_ptr<Y> && r,
+ typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() ) BOOST_SP_NOEXCEPT
+ : px( r.px ), pn( r.pn )
+ {
+ boost::detail::sp_assert_convertible< Y, T >();
+
+ r.px = 0;
+ r.pn = 0;
+ }
+
+#endif
+
+ // aliasing
+
+ template<class Y>
+ local_shared_ptr( local_shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
+ {
+ if( pn )
+ {
+ pn->add_ref();
+ }
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template<class Y>
+ local_shared_ptr( local_shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
+ {
+ r.px = 0;
+ r.pn = 0;
+ }
+
+#endif
+
+ // assignment
+
+ local_shared_ptr & operator=( local_shared_ptr const & r ) BOOST_SP_NOEXCEPT
+ {
+ local_shared_ptr( r ).swap( *this );
+ return *this;
+ }
+
+ template<class Y> local_shared_ptr & operator=( local_shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
+ {
+ local_shared_ptr( r ).swap( *this );
+ return *this;
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ local_shared_ptr & operator=( local_shared_ptr && r ) BOOST_SP_NOEXCEPT
+ {
+ local_shared_ptr( std::move( r ) ).swap( *this );
+ return *this;
+ }
+
+ template<class Y>
+ local_shared_ptr & operator=( local_shared_ptr<Y> && r ) BOOST_SP_NOEXCEPT
+ {
+ local_shared_ptr( std::move( r ) ).swap( *this );
+ return *this;
+ }
+
+#endif
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ local_shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
+ {
+ local_shared_ptr().swap(*this);
+ return *this;
+ }
+
+#endif
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template<class Y, class D>
+ local_shared_ptr & operator=( std::unique_ptr<Y, D> && r )
+ {
+ local_shared_ptr( std::move(r) ).swap( *this );
+ return *this;
+ }
+
+#endif
+
+ template<class Y, class D>
+ local_shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r ); // !
+
+ // reset
+
+ void reset() BOOST_SP_NOEXCEPT
+ {
+ local_shared_ptr().swap( *this );
+ }
+
+ template<class Y> void reset( Y * p ) // Y must be complete
+ {
+ local_shared_ptr( p ).swap( *this );
+ }
+
+ template<class Y, class D> void reset( Y * p, D d )
+ {
+ local_shared_ptr( p, d ).swap( *this );
+ }
+
+ template<class Y, class D, class A> void reset( Y * p, D d, A a )
+ {
+ local_shared_ptr( p, d, a ).swap( *this );
+ }
+
+ template<class Y> void reset( local_shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT
+ {
+ local_shared_ptr( r, p ).swap( *this );
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ template<class Y> void reset( local_shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT
+ {
+ local_shared_ptr( std::move( r ), p ).swap( *this );
+ }
+
+#endif
+
+ // accessors
+
+ typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT
+ {
+ return *px;
+ }
+
+ typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT
+ {
+ return px;
+ }
+
+ typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERT
+ {
+ BOOST_ASSERT( px != 0 );
+ BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
+
+ return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
+ }
+
+ element_type * get() const BOOST_SP_NOEXCEPT
+ {
+ return px;
+ }
+
+ // implicit conversion to "bool"
+#include <boost/smart_ptr/detail/operator_bool.hpp>
+
+ long local_use_count() const BOOST_SP_NOEXCEPT
+ {
+ return pn? pn->local_use_count(): 0;
+ }
+
+ // conversions to shared_ptr, weak_ptr
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+ template<class Y, class E = typename boost::detail::sp_enable_if_convertible<T,Y>::type> operator shared_ptr<Y>() const BOOST_SP_NOEXCEPT
+#else
+ template<class Y> operator shared_ptr<Y>() const BOOST_SP_NOEXCEPT
+#endif
+ {
+ boost::detail::sp_assert_convertible<T, Y>();
+
+ if( pn )
+ {
+ return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
+ }
+ else
+ {
+ return shared_ptr<Y>();
+ }
+ }
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+ template<class Y, class E = typename boost::detail::sp_enable_if_convertible<T,Y>::type> operator weak_ptr<Y>() const BOOST_SP_NOEXCEPT
+#else
+ template<class Y> operator weak_ptr<Y>() const BOOST_SP_NOEXCEPT
+#endif
+ {
+ boost::detail::sp_assert_convertible<T, Y>();
+
+ if( pn )
+ {
+ return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
+ }
+ else
+ {
+ return weak_ptr<Y>();
+ }
+ }
+
+ // swap
+
+ void swap( local_shared_ptr & r ) BOOST_SP_NOEXCEPT
+ {
+ std::swap( px, r.px );
+ std::swap( pn, r.pn );
+ }
+
+ // owner_before
+
+ template<class Y> bool owner_before( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
+ {
+ return std::less< boost::detail::local_counted_base* >()( pn, r.pn );
+ }
+};
+
+template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
+{
+ return a.get() == b.get();
+}
+
+template<class T, class U> inline bool operator!=( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
+{
+ return a.get() != b.get();
+}
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( local_shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator==( boost::detail::sp_nullptr_t, local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( local_shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+#endif
+
+template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
+{
+ return a.get() == b.get();
+}
+
+template<class T, class U> inline bool operator!=( local_shared_ptr<T> const & a, shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
+{
+ return a.get() != b.get();
+}
+
+template<class T, class U> inline bool operator==( shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
+{
+ return a.get() == b.get();
+}
+
+template<class T, class U> inline bool operator!=( shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
+{
+ return a.get() != b.get();
+}
+
+template<class T, class U> inline bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
+{
+ return a.owner_before( b );
+}
+
+template<class T> inline void swap( local_shared_ptr<T> & a, local_shared_ptr<T> & b ) BOOST_SP_NOEXCEPT
+{
+ a.swap( b );
+}
+
+template<class T, class U> local_shared_ptr<T> static_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
+{
+ (void) static_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename local_shared_ptr<T>::element_type E;
+
+ E * p = static_cast< E* >( r.get() );
+ return local_shared_ptr<T>( r, p );
+}
+
+template<class T, class U> local_shared_ptr<T> const_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
+{
+ (void) const_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename local_shared_ptr<T>::element_type E;
+
+ E * p = const_cast< E* >( r.get() );
+ return local_shared_ptr<T>( r, p );
+}
+
+template<class T, class U> local_shared_ptr<T> dynamic_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
+{
+ (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename local_shared_ptr<T>::element_type E;
+
+ E * p = dynamic_cast< E* >( r.get() );
+ return p? local_shared_ptr<T>( r, p ): local_shared_ptr<T>();
+}
+
+template<class T, class U> local_shared_ptr<T> reinterpret_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
+{
+ (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename local_shared_ptr<T>::element_type E;
+
+ E * p = reinterpret_cast< E* >( r.get() );
+ return local_shared_ptr<T>( r, p );
+}
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+template<class T, class U> local_shared_ptr<T> static_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
+{
+ (void) static_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename local_shared_ptr<T>::element_type E;
+
+ E * p = static_cast< E* >( r.get() );
+ return local_shared_ptr<T>( std::move(r), p );
+}
+
+template<class T, class U> local_shared_ptr<T> const_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
+{
+ (void) const_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename local_shared_ptr<T>::element_type E;
+
+ E * p = const_cast< E* >( r.get() );
+ return local_shared_ptr<T>( std::move(r), p );
+}
+
+template<class T, class U> local_shared_ptr<T> dynamic_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
+{
+ (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename local_shared_ptr<T>::element_type E;
+
+ E * p = dynamic_cast< E* >( r.get() );
+ return p? local_shared_ptr<T>( std::move(r), p ): local_shared_ptr<T>();
+}
+
+template<class T, class U> local_shared_ptr<T> reinterpret_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
+{
+ (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename local_shared_ptr<T>::element_type E;
+
+ E * p = reinterpret_cast< E* >( r.get() );
+ return local_shared_ptr<T>( std::move(r), p );
+}
+
+#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+// get_pointer() enables boost::mem_fn to recognize local_shared_ptr
+
+template<class T> inline typename local_shared_ptr<T>::element_type * get_pointer( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
+{
+ return p.get();
+}
+
+// operator<<
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+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 )
+{
+ os << p.get();
+ return os;
+}
+
+#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;
+
+template< class T > std::size_t hash_value( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
+{
+ return boost::hash< typename local_shared_ptr<T>::element_type* >()( p.get() );
+}
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
diff --git a/boost/smart_ptr/make_local_shared.hpp b/boost/smart_ptr/make_local_shared.hpp
new file mode 100644
index 0000000000..23114fea26
--- /dev/null
+++ b/boost/smart_ptr/make_local_shared.hpp
@@ -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
diff --git a/boost/smart_ptr/make_local_shared_array.hpp b/boost/smart_ptr/make_local_shared_array.hpp
new file mode 100644
index 0000000000..663f83479b
--- /dev/null
+++ b/boost/smart_ptr/make_local_shared_array.hpp
@@ -0,0 +1,67 @@
+/*
+Copyright 2017 Peter Dimov
+Copyright 2017 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+Distributed under the Boost Software License, Version 1.0.
+(http://www.boost.org/LICENSE_1_0.txt)
+*/
+#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP
+#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP
+
+#include <boost/smart_ptr/allocate_local_shared_array.hpp>
+
+namespace boost {
+
+template<class T>
+inline typename detail::lsp_if_size_array<T>::type
+make_local_shared()
+{
+ return boost::allocate_local_shared<T>(std::allocator<typename
+ detail::sp_array_scalar<T>::type>());
+}
+
+template<class T>
+inline typename detail::lsp_if_size_array<T>::type
+make_local_shared(const typename detail::sp_array_element<T>::type& value)
+{
+ return boost::allocate_local_shared<T>(std::allocator<typename
+ detail::sp_array_scalar<T>::type>(), value);
+}
+
+template<class T>
+inline typename detail::lsp_if_array<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);
+}
+
+template<class T>
+inline typename detail::lsp_if_array<T>::type
+make_local_shared(std::size_t size,
+ const typename detail::sp_array_element<T>::type& value)
+{
+ return boost::allocate_local_shared<T>(std::allocator<typename
+ detail::sp_array_scalar<T>::type>(), size, value);
+}
+
+template<class T>
+inline typename detail::lsp_if_size_array<T>::type
+make_local_shared_noinit()
+{
+ return allocate_local_shared_noinit<T>(std::allocator<typename
+ detail::sp_array_scalar<T>::type>());
+}
+
+template<class T>
+inline typename detail::lsp_if_array<T>::type
+make_local_shared_noinit(std::size_t size)
+{
+ return allocate_local_shared_noinit<T>(std::allocator<typename
+ detail::sp_array_scalar<T>::type>(), size);
+}
+
+} /* boost */
+
+#endif
diff --git a/boost/smart_ptr/make_local_shared_object.hpp b/boost/smart_ptr/make_local_shared_object.hpp
new file mode 100644
index 0000000000..ab83d60e61
--- /dev/null
+++ b/boost/smart_ptr/make_local_shared_object.hpp
@@ -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, std::allocator<T> > 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
diff --git a/boost/smart_ptr/make_shared.hpp b/boost/smart_ptr/make_shared.hpp
index 8d0e3ea400..dd9191c61d 100644
--- a/boost/smart_ptr/make_shared.hpp
+++ b/boost/smart_ptr/make_shared.hpp
@@ -9,8 +9,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
-// See http://www.boost.org/libs/smart_ptr/make_shared.html
-// for documentation.
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
#include <boost/smart_ptr/make_shared_object.hpp>
diff --git a/boost/smart_ptr/make_shared_object.hpp b/boost/smart_ptr/make_shared_object.hpp
index 3bc78ee9ae..c681602dca 100644
--- a/boost/smart_ptr/make_shared_object.hpp
+++ b/boost/smart_ptr/make_shared_object.hpp
@@ -9,14 +9,14 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
-// See http://www.boost.org/libs/smart_ptr/make_shared.html
-// for documentation.
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
#include <boost/config.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/sp_forward.hpp>
+#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <cstddef>
@@ -48,7 +48,7 @@ private:
private:
- void destroy()
+ void destroy() BOOST_SP_NOEXCEPT
{
if( initialized_ )
{
@@ -70,39 +70,39 @@ private:
public:
- sp_ms_deleter() BOOST_NOEXCEPT : initialized_( false )
+ sp_ms_deleter() BOOST_SP_NOEXCEPT : initialized_( false )
{
}
- template<class A> explicit sp_ms_deleter( A const & ) BOOST_NOEXCEPT : initialized_( false )
+ template<class A> explicit sp_ms_deleter( A const & ) BOOST_SP_NOEXCEPT : initialized_( false )
{
}
// optimization: do not copy storage_
- sp_ms_deleter( sp_ms_deleter const & ) BOOST_NOEXCEPT : initialized_( false )
+ sp_ms_deleter( sp_ms_deleter const & ) BOOST_SP_NOEXCEPT : initialized_( false )
{
}
- ~sp_ms_deleter()
+ ~sp_ms_deleter() BOOST_SP_NOEXCEPT
{
destroy();
}
- void operator()( T * )
+ void operator()( T * ) BOOST_SP_NOEXCEPT
{
destroy();
}
- static void operator_fn( T* ) // operator() can't be static
+ static void operator_fn( T* ) BOOST_SP_NOEXCEPT // operator() can't be static
{
}
- void * address() BOOST_NOEXCEPT
+ void * address() BOOST_SP_NOEXCEPT
{
return storage_.data_;
}
- void set_initialized() BOOST_NOEXCEPT
+ void set_initialized() BOOST_SP_NOEXCEPT
{
initialized_ = true;
}
@@ -120,7 +120,7 @@ private:
private:
- void destroy()
+ void destroy() BOOST_SP_NOEXCEPT
{
if( initialized_ )
{
@@ -142,35 +142,35 @@ private:
public:
- sp_as_deleter( A const & a ) BOOST_NOEXCEPT : a_( a ), initialized_( false )
+ sp_as_deleter( A const & a ) BOOST_SP_NOEXCEPT : a_( a ), initialized_( false )
{
}
// optimization: do not copy storage_
- sp_as_deleter( sp_as_deleter const & r ) BOOST_NOEXCEPT : a_( r.a_), initialized_( false )
+ sp_as_deleter( sp_as_deleter const & r ) BOOST_SP_NOEXCEPT : a_( r.a_), initialized_( false )
{
}
- ~sp_as_deleter()
+ ~sp_as_deleter() BOOST_SP_NOEXCEPT
{
destroy();
}
- void operator()( T * )
+ void operator()( T * ) BOOST_SP_NOEXCEPT
{
destroy();
}
- static void operator_fn( T* ) // operator() can't be static
+ static void operator_fn( T* ) BOOST_SP_NOEXCEPT // operator() can't be static
{
}
- void * address() BOOST_NOEXCEPT
+ void * address() BOOST_SP_NOEXCEPT
{
return storage_.data_;
}
- void set_initialized() BOOST_NOEXCEPT
+ void set_initialized() BOOST_SP_NOEXCEPT
{
initialized_ = true;
}
diff --git a/boost/smart_ptr/owner_less.hpp b/boost/smart_ptr/owner_less.hpp
index 75d182c121..5f50aeb5b8 100644
--- a/boost/smart_ptr/owner_less.hpp
+++ b/boost/smart_ptr/owner_less.hpp
@@ -11,7 +11,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
-// See http://www.boost.org/libs/smart_ptr/smart_ptr.htm for documentation.
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
namespace boost
diff --git a/boost/smart_ptr/scoped_array.hpp b/boost/smart_ptr/scoped_array.hpp
index f847c094e4..05dd05aea8 100644
--- a/boost/smart_ptr/scoped_array.hpp
+++ b/boost/smart_ptr/scoped_array.hpp
@@ -8,8 +8,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
-// http://www.boost.org/libs/smart_ptr/scoped_array.htm
-//
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
#include <boost/config.hpp>
#include <boost/assert.hpp>
@@ -62,7 +61,7 @@ public:
#endif
}
- ~scoped_array() // never throws
+ ~scoped_array() BOOST_SP_NOEXCEPT
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_array_destructor_hook( px );
@@ -70,20 +69,20 @@ public:
boost::checked_array_delete( px );
}
- void reset(T * p = 0) // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+ void reset(T * p = 0) BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
- T & operator[](std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+ T & operator[](std::ptrdiff_t i) const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
BOOST_ASSERT( i >= 0 );
return px[i];
}
- T * get() const BOOST_NOEXCEPT
+ T * get() const BOOST_SP_NOEXCEPT
{
return px;
}
@@ -91,7 +90,7 @@ public:
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
- void swap(scoped_array & b) BOOST_NOEXCEPT
+ void swap(scoped_array & b) BOOST_SP_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
@@ -101,29 +100,29 @@ public:
#if !defined( BOOST_NO_CXX11_NULLPTR )
-template<class T> inline bool operator==( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator!=( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
-template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
-template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_NOEXCEPT
+template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_SP_NOEXCEPT
{
a.swap(b);
}
diff --git a/boost/smart_ptr/scoped_ptr.hpp b/boost/smart_ptr/scoped_ptr.hpp
index 8fd8a180fb..5325eba5ff 100644
--- a/boost/smart_ptr/scoped_ptr.hpp
+++ b/boost/smart_ptr/scoped_ptr.hpp
@@ -8,8 +8,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
-// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
-//
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
#include <boost/config.hpp>
#include <boost/assert.hpp>
@@ -63,7 +62,7 @@ public:
typedef T element_type;
- explicit scoped_ptr( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p ) // never throws
+ explicit scoped_ptr( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px );
@@ -72,7 +71,7 @@ public:
#ifndef BOOST_NO_AUTO_PTR
- explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
+ explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_SP_NOEXCEPT : px( p.release() )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px );
@@ -81,7 +80,7 @@ public:
#endif
- ~scoped_ptr() // never throws
+ ~scoped_ptr() BOOST_SP_NOEXCEPT
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px );
@@ -89,25 +88,25 @@ public:
boost::checked_delete( px );
}
- void reset(T * p = 0) // never throws
+ void reset(T * p = 0) BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
- T & operator*() const // never throws
+ T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return *px;
}
- T * operator->() const // never throws
+ T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return px;
}
- T * get() const BOOST_NOEXCEPT
+ T * get() const BOOST_SP_NOEXCEPT
{
return px;
}
@@ -115,7 +114,7 @@ public:
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
- void swap(scoped_ptr & b) BOOST_NOEXCEPT
+ void swap(scoped_ptr & b) BOOST_SP_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
@@ -125,36 +124,36 @@ public:
#if !defined( BOOST_NO_CXX11_NULLPTR )
-template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
-template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
-template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
+template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_SP_NOEXCEPT
{
a.swap(b);
}
// get_pointer(p) is a generic way to say p.get()
-template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
+template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_SP_NOEXCEPT
{
return p.get();
}
diff --git a/boost/smart_ptr/shared_array.hpp b/boost/smart_ptr/shared_array.hpp
index 2e5cb134a3..3ffa7426c3 100644
--- a/boost/smart_ptr/shared_array.hpp
+++ b/boost/smart_ptr/shared_array.hpp
@@ -11,7 +11,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
-// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/config.hpp> // for broken compiler workarounds
@@ -120,7 +120,7 @@ public:
shared_array( shared_array<Y> const & r )
#endif
- BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws
+ BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
{
boost::detail::sp_assert_convertible< Y[], T[] >();
}
@@ -128,7 +128,7 @@ public:
// aliasing
template< class Y >
- shared_array( shared_array<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
+ shared_array( shared_array<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
{
}
@@ -143,7 +143,7 @@ public:
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
template<class Y>
- shared_array & operator=( shared_array<Y> const & r ) BOOST_NOEXCEPT
+ shared_array & operator=( shared_array<Y> const & r ) BOOST_SP_NOEXCEPT
{
this_type( r ).swap( *this );
return *this;
@@ -160,7 +160,7 @@ public:
}
template<class Y>
- shared_array & operator=( shared_array<Y> && r ) BOOST_NOEXCEPT
+ shared_array & operator=( shared_array<Y> && r ) BOOST_SP_NOEXCEPT
{
this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
return *this;
@@ -168,7 +168,7 @@ public:
#endif
- void reset() BOOST_NOEXCEPT
+ void reset() BOOST_SP_NOEXCEPT
{
this_type().swap( *this );
}
@@ -189,19 +189,19 @@ public:
this_type( p, d, a ).swap( *this );
}
- template<class Y> void reset( shared_array<Y> const & r, element_type * p )
+ template<class Y> void reset( shared_array<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT
{
this_type( r, p ).swap( *this );
}
- T & operator[] (std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+ T & operator[] (std::ptrdiff_t i) const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT(px != 0);
BOOST_ASSERT(i >= 0);
return px[i];
}
- T * get() const BOOST_NOEXCEPT
+ T * get() const BOOST_SP_NOEXCEPT
{
return px;
}
@@ -209,23 +209,23 @@ public:
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
- bool unique() const BOOST_NOEXCEPT
+ bool unique() const BOOST_SP_NOEXCEPT
{
return pn.unique();
}
- long use_count() const BOOST_NOEXCEPT
+ long use_count() const BOOST_SP_NOEXCEPT
{
return pn.use_count();
}
- void swap(shared_array<T> & other) BOOST_NOEXCEPT
+ void swap(shared_array<T> & other) BOOST_SP_NOEXCEPT
{
std::swap(px, other.px);
pn.swap(other.pn);
}
- void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
+ void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
{
return pn.get_deleter( ti );
}
@@ -239,51 +239,51 @@ private:
}; // shared_array
-template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
+template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_SP_NOEXCEPT
{
return a.get() == b.get();
}
-template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
+template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
-template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
-template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
-template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
+template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_SP_NOEXCEPT
{
return std::less<T*>()(a.get(), b.get());
}
-template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_NOEXCEPT
+template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_SP_NOEXCEPT
{
a.swap(b);
}
-template< class D, class T > D * get_deleter( shared_array<T> const & p )
+template< class D, class T > D * get_deleter( shared_array<T> const & p ) BOOST_SP_NOEXCEPT
{
return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
}
diff --git a/boost/smart_ptr/shared_ptr.hpp b/boost/smart_ptr/shared_ptr.hpp
index e33707b3bc..e8a302c74a 100644
--- a/boost/smart_ptr/shared_ptr.hpp
+++ b/boost/smart_ptr/shared_ptr.hpp
@@ -11,7 +11,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
-// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/config.hpp> // for broken compiler workarounds
@@ -262,7 +262,7 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
// sp_assert_convertible
-template< class Y, class T > inline void sp_assert_convertible()
+template< class Y, class T > inline void sp_assert_convertible() BOOST_SP_NOEXCEPT
{
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
@@ -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
@@ -345,13 +349,25 @@ public:
typedef typename boost::detail::sp_element< T >::type element_type;
- shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
+ BOOST_CONSTEXPR shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn()
{
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
- shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws
+ BOOST_CONSTEXPR shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn()
+ {
+ }
+
+#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_ ) )
{
}
@@ -420,7 +436,7 @@ public:
template<class Y>
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )
- BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
+ BOOST_SP_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
{
if( !pn.empty() )
{
@@ -438,14 +454,14 @@ public:
shared_ptr( shared_ptr<Y> const & r )
#endif
- BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
+ BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
{
boost::detail::sp_assert_convertible< Y, T >();
}
// aliasing
template< class Y >
- shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
+ shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
{
}
@@ -502,9 +518,12 @@ public:
boost::detail::sp_assert_convertible< Y, T >();
typename std::unique_ptr< Y, D >::pointer tmp = r.get();
- pn = boost::detail::shared_count( r );
- boost::detail::sp_deleter_construct( this, tmp );
+ if( tmp != 0 )
+ {
+ pn = boost::detail::shared_count( r );
+ boost::detail::sp_deleter_construct( this, tmp );
+ }
}
#endif
@@ -515,9 +534,12 @@ public:
boost::detail::sp_assert_convertible< Y, T >();
typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get();
- pn = boost::detail::shared_count( r );
- boost::detail::sp_deleter_construct( this, tmp );
+ if( tmp != 0 )
+ {
+ pn = boost::detail::shared_count( r );
+ boost::detail::sp_deleter_construct( this, tmp );
+ }
}
// assignment
@@ -531,7 +553,7 @@ public:
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
template<class Y>
- shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_NOEXCEPT
+ shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_SP_NOEXCEPT
{
this_type(r).swap(*this);
return *this;
@@ -592,10 +614,13 @@ public:
shared_ptr tmp;
- tmp.px = p;
- tmp.pn = boost::detail::shared_count( r );
+ if( p != 0 )
+ {
+ tmp.px = p;
+ tmp.pn = boost::detail::shared_count( r );
- boost::detail::sp_deleter_construct( &tmp, p );
+ boost::detail::sp_deleter_construct( &tmp, p );
+ }
tmp.swap( *this );
@@ -622,7 +647,7 @@ public:
shared_ptr( shared_ptr<Y> && r )
#endif
- BOOST_NOEXCEPT : px( r.px ), pn()
+ BOOST_SP_NOEXCEPT : px( r.px ), pn()
{
boost::detail::sp_assert_convertible< Y, T >();
@@ -637,7 +662,7 @@ public:
}
template<class Y>
- shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_NOEXCEPT
+ shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_SP_NOEXCEPT
{
this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
return *this;
@@ -645,7 +670,7 @@ public:
// aliasing move
template<class Y>
- shared_ptr( shared_ptr<Y> && r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn()
+ shared_ptr( shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn()
{
pn.swap( r.pn );
r.px = 0;
@@ -655,7 +680,7 @@ public:
#if !defined( BOOST_NO_CXX11_NULLPTR )
- shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws
+ shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
this_type().swap(*this);
return *this;
@@ -663,7 +688,7 @@ public:
#endif
- void reset() BOOST_NOEXCEPT // never throws in 1.30+
+ void reset() BOOST_SP_NOEXCEPT
{
this_type().swap(*this);
}
@@ -684,36 +709,33 @@ public:
this_type( p, d, a ).swap( *this );
}
- template<class Y> void reset( shared_ptr<Y> const & r, element_type * p )
+ template<class Y> void reset( shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT
{
this_type( r, p ).swap( *this );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
- template<class Y> void reset( shared_ptr<Y> && r, element_type * p )
+ template<class Y> void reset( shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT
{
this_type( static_cast< shared_ptr<Y> && >( r ), p ).swap( *this );
}
#endif
- // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
- typename boost::detail::sp_dereference< T >::type operator* () const
+ typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return *px;
}
- // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
- typename boost::detail::sp_member_access< T >::type operator-> () const
+ typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return px;
}
- // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
- typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
+ typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
@@ -721,7 +743,7 @@ public:
return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
}
- element_type * get() const BOOST_NOEXCEPT
+ element_type * get() const BOOST_SP_NOEXCEPT
{
return px;
}
@@ -729,47 +751,57 @@ public:
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
- bool unique() const BOOST_NOEXCEPT
+ bool unique() const BOOST_SP_NOEXCEPT
{
return pn.unique();
}
- long use_count() const BOOST_NOEXCEPT
+ long use_count() const BOOST_SP_NOEXCEPT
{
return pn.use_count();
}
- void swap( shared_ptr & other ) BOOST_NOEXCEPT
+ void swap( shared_ptr & other ) BOOST_SP_NOEXCEPT
{
std::swap(px, other.px);
pn.swap(other.pn);
}
- template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+ template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn < rhs.pn;
}
- template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+ template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn < rhs.pn;
}
- void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT
+ void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
{
return pn.get_deleter( ti );
}
- void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT
+ 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();
}
- bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT
+ bool _internal_equiv( shared_ptr const & r ) const BOOST_SP_NOEXCEPT
{
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)
@@ -788,12 +820,12 @@ private:
}; // shared_ptr
-template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
+template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.get() == b.get();
}
-template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
+template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
@@ -802,7 +834,7 @@ template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, share
// Resolve the ambiguity between our op!= and the one in rel_ops
-template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT
+template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_SP_NOEXCEPT
{
return a.get() != b.get();
}
@@ -811,39 +843,39 @@ template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T>
#if !defined( BOOST_NO_CXX11_NULLPTR )
-template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
-template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
-template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
+template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
-template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
+template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.owner_before( b );
}
-template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT
+template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_SP_NOEXCEPT
{
a.swap(b);
}
-template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
+template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
{
(void) static_cast< T* >( static_cast< U* >( 0 ) );
@@ -853,7 +885,7 @@ template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> cons
return shared_ptr<T>( r, p );
}
-template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
+template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
{
(void) const_cast< T* >( static_cast< U* >( 0 ) );
@@ -863,7 +895,7 @@ template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const
return shared_ptr<T>( r, p );
}
-template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
+template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
{
(void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
@@ -873,7 +905,7 @@ template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> con
return p? shared_ptr<T>( r, p ): shared_ptr<T>();
}
-template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
+template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
{
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
@@ -885,7 +917,7 @@ template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U>
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
-template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT
+template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) static_cast< T* >( static_cast< U* >( 0 ) );
@@ -895,7 +927,7 @@ template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r
return shared_ptr<T>( std::move(r), p );
}
-template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT
+template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) const_cast< T* >( static_cast< U* >( 0 ) );
@@ -905,7 +937,7 @@ template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r
return shared_ptr<T>( std::move(r), p );
}
-template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT
+template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
@@ -915,7 +947,7 @@ template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> &&
return p? shared_ptr<T>( std::move(r), p ): shared_ptr<T>();
}
-template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT
+template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
{
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
@@ -929,7 +961,7 @@ template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U>
// get_pointer() enables boost::mem_fn to recognize shared_ptr
-template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_NOEXCEPT
+template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_SP_NOEXCEPT
{
return p.get();
}
@@ -974,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_NOEXCEPT
+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
{
@@ -1008,17 +1026,17 @@ public:
{
}
- template< class T > void set_deleter( shared_ptr<T> const & deleter )
+ template< class T > void set_deleter( shared_ptr<T> const & deleter ) BOOST_SP_NOEXCEPT
{
deleter_ = deleter;
}
- template<typename D> D* get_deleter() const BOOST_NOEXCEPT
+ template<typename D> D* get_deleter() const BOOST_SP_NOEXCEPT
{
return boost::detail::basic_get_deleter<D>( deleter_ );
}
- template< class T> void operator()( T* )
+ template< class T> void operator()( T* ) BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( deleter_.use_count() <= 1 );
deleter_.reset();
@@ -1027,53 +1045,58 @@ public:
} // namespace detail
-template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
+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( d == 0 )
+ {
+ d = boost::detail::basic_get_local_deleter( d, p );
+ }
- if(del == 0)
+ 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
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
-template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_NOEXCEPT
+template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_SP_NOEXCEPT
{
return false;
}
-template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
+template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) BOOST_SP_NOEXCEPT
{
boost::detail::spinlock_pool<2>::scoped_lock lock( p );
return *p;
}
-template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ int )
+template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ int ) BOOST_SP_NOEXCEPT
{
return atomic_load( p );
}
-template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
+template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) BOOST_SP_NOEXCEPT
{
boost::detail::spinlock_pool<2>::scoped_lock lock( p );
p->swap( r );
}
-template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int )
+template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int ) BOOST_SP_NOEXCEPT
{
atomic_store( p, r ); // std::move( r )
}
-template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
+template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) BOOST_SP_NOEXCEPT
{
boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
@@ -1084,12 +1107,12 @@ template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T
return r; // return std::move( r )
}
-template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int )
+template<class T> shared_ptr<T> inline atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int ) BOOST_SP_NOEXCEPT
{
return atomic_exchange( p, r ); // std::move( r )
}
-template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w )
+template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
{
boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
@@ -1114,7 +1137,7 @@ template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T>
}
}
-template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ int, /*memory_order failure*/ int )
+template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ int, /*memory_order failure*/ int ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( p, v, w ); // std::move( w )
}
@@ -1125,13 +1148,35 @@ template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> *
template< class T > struct hash;
-template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_NOEXCEPT
+template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return boost::hash< typename boost::shared_ptr<T>::element_type* >()( p.get() );
}
} // 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
diff --git a/boost/smart_ptr/weak_ptr.hpp b/boost/smart_ptr/weak_ptr.hpp
index f3411f7225..54d9ef3781 100644
--- a/boost/smart_ptr/weak_ptr.hpp
+++ b/boost/smart_ptr/weak_ptr.hpp
@@ -6,11 +6,11 @@
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov
//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
//
-// See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
+// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <memory> // boost.TR1 include order fix
@@ -32,7 +32,7 @@ public:
typedef typename boost::detail::sp_element< T >::type element_type;
- weak_ptr() BOOST_SP_NOEXCEPT : px(0), pn() // never throws in 1.30+
+ BOOST_CONSTEXPR weak_ptr() BOOST_SP_NOEXCEPT : px(0), pn()
{
}
@@ -59,7 +59,7 @@ public:
// The "obvious" converting constructor implementation:
//
// template<class Y>
-// weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
+// weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn)
// {
// }
//
@@ -82,7 +82,7 @@ public:
weak_ptr( weak_ptr<Y> const & r )
#endif
- BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn)
+ BOOST_SP_NOEXCEPT : px(r.lock().get()), pn(r.pn)
{
boost::detail::sp_assert_convertible< Y, T >();
}
@@ -99,7 +99,7 @@ public:
weak_ptr( weak_ptr<Y> && r )
#endif
- BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
+ BOOST_SP_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
{
boost::detail::sp_assert_convertible< Y, T >();
r.px = 0;
@@ -132,7 +132,7 @@ public:
weak_ptr( shared_ptr<Y> const & r )
#endif
- BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
+ BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
{
boost::detail::sp_assert_convertible< Y, T >();
}
@@ -140,7 +140,7 @@ public:
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
template<class Y>
- weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT
+ weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
{
boost::detail::sp_assert_convertible< Y, T >();
@@ -153,7 +153,7 @@ public:
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y>
- weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
+ weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_SP_NOEXCEPT
{
this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
return *this;
@@ -162,7 +162,7 @@ public:
#endif
template<class Y>
- weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT
+ weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
{
boost::detail::sp_assert_convertible< Y, T >();
@@ -174,50 +174,50 @@ public:
#endif
- shared_ptr<T> lock() const BOOST_NOEXCEPT
+ shared_ptr<T> lock() const BOOST_SP_NOEXCEPT
{
return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
}
- long use_count() const BOOST_NOEXCEPT
+ long use_count() const BOOST_SP_NOEXCEPT
{
return pn.use_count();
}
- bool expired() const BOOST_NOEXCEPT
+ bool expired() const BOOST_SP_NOEXCEPT
{
return pn.use_count() == 0;
}
- bool _empty() const // extension, not in std::weak_ptr
+ bool _empty() const BOOST_SP_NOEXCEPT // extension, not in std::weak_ptr
{
return pn.empty();
}
- void reset() BOOST_NOEXCEPT // never throws in 1.30+
+ void reset() BOOST_SP_NOEXCEPT
{
this_type().swap(*this);
}
- void swap(this_type & other) BOOST_NOEXCEPT
+ void swap(this_type & other) BOOST_SP_NOEXCEPT
{
std::swap(px, other.px);
pn.swap(other.pn);
}
template<typename Y>
- void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
+ void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2) BOOST_SP_NOEXCEPT
{
px = px2;
pn = r.pn;
}
- template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+ template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn < rhs.pn;
}
- template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+ template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn < rhs.pn;
}
@@ -239,12 +239,12 @@ private:
}; // weak_ptr
-template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_NOEXCEPT
+template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_SP_NOEXCEPT
{
return a.owner_before( b );
}
-template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_NOEXCEPT
+template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_SP_NOEXCEPT
{
a.swap(b);
}