Compare commits

...

6 Commits

Author SHA1 Message Date
Peter Dimov
4fbb9ff076 Merge branch 'develop' 2019-03-02 21:08:43 +02:00
Glen Fernandes
8ccb36dfcf Use traits from TypeTraits 2019-02-22 19:36:32 -05:00
Glen Fernandes
fde2e91443 Use traits from TypeTraits 2019-02-22 19:01:55 -05:00
Peter Dimov
aa1341a6a2 Add BOOST_SP_NOEXCEPT to sp_counted_base_nt.hpp 2019-01-28 21:24:09 +02:00
Peter Dimov
053779f3ee Add BOOST_SP_NOEXCEPT to sp_counted_base_clang.hpp 2019-01-28 20:52:28 +02:00
Peter Dimov
51d8167fbf Add more BOOST_SP_NOEXCEPT 2019-01-28 18:46:39 +02:00
15 changed files with 253 additions and 363 deletions

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2017 Glen Joseph Fernandes Copyright 2017-2019 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -14,22 +14,6 @@ Distributed under the Boost Software License, Version 1.0.
namespace boost { namespace boost {
namespace detail { 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 BOOST_SYMBOL_VISIBLE lsp_array_base class BOOST_SYMBOL_VISIBLE lsp_array_base
: public local_counted_base { : public local_counted_base {
public: public:
@@ -84,15 +68,16 @@ private:
} /* detail */ } /* detail */
template<class T, class A> template<class T, class A>
inline typename detail::lsp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, std::size_t count) allocate_local_shared(const A& allocator, std::size_t count)
{ {
typedef typename detail::sp_array_element<T>::type type; typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar; typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_array_state<other> state; typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type, scalar>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node); scalar* start = detail::sp_array_start<base, scalar>(node);
@@ -105,15 +90,16 @@ allocate_local_shared(const A& allocator, std::size_t count)
} }
template<class T, class A> template<class T, class A>
inline typename detail::lsp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator) allocate_local_shared(const A& allocator)
{ {
enum { typedef typename remove_extent<T>::type type;
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_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
typedef detail::lsp_size_array_state<other, size> state; typedef detail::lsp_size_array_state<other, size> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
@@ -128,22 +114,25 @@ allocate_local_shared(const A& allocator)
} }
template<class T, class A> template<class T, class A>
inline typename detail::lsp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, std::size_t count, allocate_local_shared(const A& allocator, std::size_t count,
const typename detail::sp_array_element<T>::type& value) const typename remove_extent<T>::type& value)
{ {
typedef typename detail::sp_array_element<T>::type type; typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar; typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_array_state<other> state; typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value; enum {
total = detail::sp_array_count<type, scalar>::value
};
std::size_t size = count * total;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node); scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, ::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), reinterpret_cast<const scalar*>(&value), total, start);
detail::sp_array_count<type>::value, start);
detail::lsp_array_base& local = node->state().base(); detail::lsp_array_base& local = node->state().base();
local.set(node); local.set(node);
result.release(); result.release();
@@ -152,16 +141,17 @@ allocate_local_shared(const A& allocator, std::size_t count,
} }
template<class T, class A> template<class T, class A>
inline typename detail::lsp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, allocate_local_shared(const A& allocator,
const typename detail::sp_array_element<T>::type& value) const typename remove_extent<T>::type& value)
{ {
enum { typedef typename remove_extent<T>::type type;
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_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
typedef detail::lsp_size_array_state<other, size> state; typedef detail::lsp_size_array_state<other, size> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
@@ -169,7 +159,7 @@ allocate_local_shared(const A& allocator,
scalar* start = detail::sp_array_start<base, scalar>(node); scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, ::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value, start); detail::sp_array_count<type, scalar>::value, start);
detail::lsp_array_base& local = node->state().base(); detail::lsp_array_base& local = node->state().base();
local.set(node); local.set(node);
result.release(); result.release();
@@ -178,15 +168,16 @@ allocate_local_shared(const A& allocator,
} }
template<class T, class A> template<class T, class A>
inline typename detail::lsp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator, std::size_t count) allocate_local_shared_noinit(const A& allocator, std::size_t count)
{ {
typedef typename detail::sp_array_element<T>::type type; typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar; typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_array_state<other> state; typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state, false> base; typedef detail::sp_array_base<state, false> base;
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type, scalar>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node); scalar* start = detail::sp_array_start<base, scalar>(node);
@@ -200,15 +191,16 @@ allocate_local_shared_noinit(const A& allocator, std::size_t count)
} }
template<class T, class A> template<class T, class A>
inline typename detail::lsp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator) allocate_local_shared_noinit(const A& allocator)
{ {
enum { typedef typename remove_extent<T>::type type;
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_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
typedef detail::lsp_size_array_state<other, size> state; typedef detail::lsp_size_array_state<other, size> state;
typedef detail::sp_array_base<state, false> base; typedef detail::sp_array_base<state, false> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2012-2018 Glen Joseph Fernandes Copyright 2012-2019 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -10,99 +10,30 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/smart_ptr/shared_ptr.hpp> #include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/type_traits/alignment_of.hpp> #include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/is_bounded_array.hpp>
#include <boost/type_traits/is_unbounded_array.hpp>
#include <boost/type_traits/has_trivial_assign.hpp> #include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp> #include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp> #include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/remove_all_extents.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/type_with_alignment.hpp> #include <boost/type_traits/type_with_alignment.hpp>
namespace boost { namespace boost {
namespace detail { namespace detail {
template<class>
struct sp_if_array { };
template<class T>
struct sp_if_array<T[]> {
typedef boost::shared_ptr<T[]> type;
};
template<class>
struct sp_if_size_array { };
template<class T, std::size_t N>
struct sp_if_size_array<T[N]> {
typedef boost::shared_ptr<T[N]> type;
};
template<class>
struct sp_array_element { };
template<class T>
struct sp_array_element<T[]> {
typedef T type;
};
template<class T, std::size_t N>
struct sp_array_element<T[N]> {
typedef T type;
};
template<class T> template<class T>
struct sp_array_scalar { struct sp_array_scalar {
typedef T type; typedef typename boost::remove_cv<typename
boost::remove_all_extents<T>::type>::type type;
}; };
template<class T, std::size_t N> template<class T, class U>
struct sp_array_scalar<T[N]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T, std::size_t N>
struct sp_array_scalar<const T[N]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T, std::size_t N>
struct sp_array_scalar<volatile T[N]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T, std::size_t N>
struct sp_array_scalar<const volatile T[N]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_scalar<T[]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_scalar<const T[]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_scalar<volatile T[]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_scalar<const volatile T[]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_count { struct sp_array_count {
enum { enum {
value = 1 value = sizeof(T) / sizeof(U)
};
};
template<class T, std::size_t N>
struct sp_array_count<T[N]> {
enum {
value = N * sp_array_count<T>::value
}; };
}; };
@@ -139,20 +70,13 @@ sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
return (size + sizeof(T) - 1) / sizeof(T); return (size + sizeof(T) - 1) / sizeof(T);
} }
template<bool, class = void>
struct sp_enable { };
template<class T>
struct sp_enable<true, T> {
typedef T type;
};
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<!E && boost::has_trivial_destructor<T>::value>::type inline typename boost::enable_if_<!E &&
boost::has_trivial_destructor<T>::value>::type
sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { } sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<!E && inline typename boost::enable_if_<!E &&
!boost::has_trivial_destructor<T>::value>::type !boost::has_trivial_destructor<T>::value>::type
sp_array_destroy(A&, T* ptr, std::size_t size) sp_array_destroy(A&, T* ptr, std::size_t size)
{ {
@@ -163,7 +87,7 @@ sp_array_destroy(A&, T* ptr, std::size_t size)
#if !defined(BOOST_NO_CXX11_ALLOCATOR) #if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<E>::type inline typename boost::enable_if_<E>::type
sp_array_destroy(A& allocator, T* ptr, std::size_t size) sp_array_destroy(A& allocator, T* ptr, std::size_t size)
{ {
while (size > 0) { while (size > 0) {
@@ -198,7 +122,7 @@ private:
}; };
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<!E && inline typename boost::enable_if_<!E &&
boost::has_trivial_constructor<T>::value && boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value && boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value>::type boost::has_trivial_destructor<T>::value>::type
@@ -210,7 +134,7 @@ sp_array_construct(A&, T* ptr, std::size_t size)
} }
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<!E && inline typename boost::enable_if_<!E &&
boost::has_trivial_constructor<T>::value && boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value && boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value>::type boost::has_trivial_destructor<T>::value>::type
@@ -223,7 +147,7 @@ sp_array_construct(A&, T* ptr, std::size_t size, const T* list,
} }
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<!E && inline typename boost::enable_if_<!E &&
!(boost::has_trivial_constructor<T>::value && !(boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value && boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value)>::type boost::has_trivial_destructor<T>::value)>::type
@@ -237,7 +161,7 @@ sp_array_construct(A& none, T* ptr, std::size_t size)
} }
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<!E && inline typename boost::enable_if_<!E &&
!(boost::has_trivial_constructor<T>::value && !(boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value && boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value)>::type boost::has_trivial_destructor<T>::value)>::type
@@ -253,7 +177,7 @@ sp_array_construct(A& none, T* ptr, std::size_t size, const T* list,
#if !defined(BOOST_NO_CXX11_ALLOCATOR) #if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<E>::type inline typename boost::enable_if_<E>::type
sp_array_construct(A& allocator, T* ptr, std::size_t size) sp_array_construct(A& allocator, T* ptr, std::size_t size)
{ {
sp_destroyer<E, A, T> hold(allocator, ptr); sp_destroyer<E, A, T> hold(allocator, ptr);
@@ -264,7 +188,7 @@ sp_array_construct(A& allocator, T* ptr, std::size_t size)
} }
template<bool E, class A, class T> template<bool E, class A, class T>
inline typename sp_enable<E>::type inline typename boost::enable_if_<E>::type
sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list, sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
std::size_t count) std::size_t count)
{ {
@@ -278,11 +202,13 @@ sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
#endif #endif
template<class A, class T> template<class A, class T>
inline typename sp_enable<boost::has_trivial_constructor<T>::value>::type inline typename
boost::enable_if_<boost::has_trivial_constructor<T>::value>::type
sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { } sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
template<class A, class T> template<class A, class T>
inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type inline typename
boost::enable_if_<!boost::has_trivial_constructor<T>::value>::type
sp_array_default(A& none, T* ptr, std::size_t size) sp_array_default(A& none, T* ptr, std::size_t size)
{ {
sp_destroyer<false, A, T> hold(none, ptr); sp_destroyer<false, A, T> hold(none, ptr);
@@ -455,27 +381,27 @@ public:
return state_; return state_;
} }
virtual void dispose() { virtual void dispose() BOOST_SP_NOEXCEPT {
sp_array_destroy<E>(state_.allocator(), sp_array_destroy<E>(state_.allocator(),
sp_array_start<sp_array_base, type>(this), state_.size()); sp_array_start<sp_array_base, type>(this), state_.size());
} }
virtual void destroy() { virtual void destroy() BOOST_SP_NOEXCEPT {
sp_array_creator<allocator, sp_array_base> other(state_.allocator(), sp_array_creator<allocator, sp_array_base> other(state_.allocator(),
state_.size()); state_.size());
this->~sp_array_base(); this->~sp_array_base();
other.destroy(this); other.destroy(this);
} }
virtual void* get_deleter(const sp_typeinfo&) { virtual void* get_deleter(const sp_typeinfo&) BOOST_SP_NOEXCEPT {
return 0; return 0;
} }
virtual void* get_local_deleter(const sp_typeinfo&) { virtual void* get_local_deleter(const sp_typeinfo&) BOOST_SP_NOEXCEPT {
return 0; return 0;
} }
virtual void* get_untyped_deleter() { virtual void* get_untyped_deleter() BOOST_SP_NOEXCEPT {
return 0; return 0;
} }
@@ -516,15 +442,15 @@ private:
} /* detail */ } /* detail */
template<class T, class A> template<class T, class A>
inline typename detail::sp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count) allocate_shared(const A& allocator, std::size_t count)
{ {
typedef typename detail::sp_array_element<T>::type type; typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar; typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_array_state<other> state; typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type, scalar>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get(); detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node); scalar* start = detail::sp_array_start<base, scalar>(node);
@@ -535,15 +461,15 @@ allocate_shared(const A& allocator, std::size_t count)
} }
template<class T, class A> template<class T, class A>
inline typename detail::sp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator) allocate_shared(const A& allocator)
{ {
enum { typedef typename remove_extent<T>::type type;
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_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
typedef detail::sp_size_array_state<other, size> state; typedef detail::sp_size_array_state<other, size> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
@@ -556,38 +482,40 @@ allocate_shared(const A& allocator)
} }
template<class T, class A> template<class T, class A>
inline typename detail::sp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count, allocate_shared(const A& allocator, std::size_t count,
const typename detail::sp_array_element<T>::type& value) const typename remove_extent<T>::type& value)
{ {
typedef typename detail::sp_array_element<T>::type type; typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar; typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_array_state<other> state; typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value; enum {
total = detail::sp_array_count<type, scalar>::value
};
std::size_t size = count * total;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get(); detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node); scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, ::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), reinterpret_cast<const scalar*>(&value), total, start);
detail::sp_array_count<type>::value, start);
result.release(); result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node)); reinterpret_cast<type*>(start), detail::shared_count(node));
} }
template<class T, class A> template<class T, class A>
inline typename detail::sp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, allocate_shared(const A& allocator,
const typename detail::sp_array_element<T>::type& value) const typename remove_extent<T>::type& value)
{ {
enum { typedef typename remove_extent<T>::type type;
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_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
typedef detail::sp_size_array_state<other, size> state; typedef detail::sp_size_array_state<other, size> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
@@ -595,22 +523,22 @@ allocate_shared(const A& allocator,
scalar* start = detail::sp_array_start<base, scalar>(node); scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, ::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value, start); detail::sp_array_count<type, scalar>::value, start);
result.release(); result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node)); reinterpret_cast<type*>(start), detail::shared_count(node));
} }
template<class T, class A> template<class T, class A>
inline typename detail::sp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator, std::size_t count) allocate_shared_noinit(const A& allocator, std::size_t count)
{ {
typedef typename detail::sp_array_element<T>::type type; typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar; typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_array_state<other> state; typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state, false> base; typedef detail::sp_array_base<state, false> base;
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type, scalar>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get(); detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node); scalar* start = detail::sp_array_start<base, scalar>(node);
@@ -622,15 +550,15 @@ allocate_shared_noinit(const A& allocator, std::size_t count)
} }
template<class T, class A> template<class T, class A>
inline typename detail::sp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator) allocate_shared_noinit(const A& allocator)
{ {
enum { typedef typename remove_extent<T>::type type;
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_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other; typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
typedef detail::sp_size_array_state<other, size> state; typedef detail::sp_size_array_state<other, size> state;
typedef detail::sp_array_base<state, false> base; typedef detail::sp_array_base<state, false> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);

View File

@@ -101,13 +101,13 @@ private:
public: public:
explicit local_counted_impl( shared_count const& pn ): pn_( pn ) explicit local_counted_impl( shared_count const& pn ) BOOST_SP_NOEXCEPT: pn_( pn )
{ {
} }
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) ) explicit local_counted_impl( shared_count && pn ) BOOST_SP_NOEXCEPT: pn_( std::move(pn) )
{ {
} }

View File

@@ -50,7 +50,7 @@ public:
#endif #endif
D& deleter() D& deleter() BOOST_SP_NOEXCEPT
{ {
return d_; return d_;
} }
@@ -74,12 +74,12 @@ template<> class local_sp_deleter<void>
{ {
}; };
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT
{ {
return &p->deleter(); return &p->deleter();
} }
inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) BOOST_SP_NOEXCEPT
{ {
return 0; return 0;
} }

View File

@@ -29,7 +29,8 @@
#include <boost/smart_ptr/detail/sp_counted_base.hpp> #include <boost/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/smart_ptr/detail/sp_counted_impl.hpp> #include <boost/smart_ptr/detail/sp_counted_impl.hpp>
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp> #include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
#include <boost/detail/workaround.hpp> #include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config/workaround.hpp>
// In order to avoid circular dependencies with Boost.TR1 // In order to avoid circular dependencies with Boost.TR1
// we make sure that our include of <memory> doesn't try to // we make sure that our include of <memory> doesn't try to
// pull in the TR1 headers: that's why we use this header // pull in the TR1 headers: that's why we use this header
@@ -118,14 +119,14 @@ private:
public: public:
BOOST_CONSTEXPR shared_count(): pi_(0) // nothrow BOOST_CONSTEXPR shared_count() BOOST_SP_NOEXCEPT: pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id) , id_(shared_count_id)
#endif #endif
{ {
} }
BOOST_CONSTEXPR explicit shared_count( sp_counted_base * pi ): pi_( pi ) // nothrow BOOST_CONSTEXPR explicit shared_count( sp_counted_base * pi ) BOOST_SP_NOEXCEPT: pi_( pi )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id) , id_(shared_count_id)
#endif #endif
@@ -421,7 +422,7 @@ public:
r.release(); r.release();
} }
~shared_count() // nothrow ~shared_count() /*BOOST_SP_NOEXCEPT*/
{ {
if( pi_ != 0 ) pi_->release(); if( pi_ != 0 ) pi_->release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
@@ -429,7 +430,7 @@ public:
#endif #endif
} }
shared_count(shared_count const & r): pi_(r.pi_) // nothrow shared_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id) , id_(shared_count_id)
#endif #endif
@@ -439,7 +440,7 @@ public:
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
shared_count(shared_count && r): pi_(r.pi_) // nothrow shared_count(shared_count && r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id) , id_(shared_count_id)
#endif #endif
@@ -450,9 +451,9 @@ public:
#endif #endif
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0 shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_SP_NOEXCEPT; // constructs an empty *this when r.use_count() == 0
shared_count & operator= (shared_count const & r) // nothrow shared_count & operator= (shared_count const & r) BOOST_SP_NOEXCEPT
{ {
sp_counted_base * tmp = r.pi_; sp_counted_base * tmp = r.pi_;
@@ -466,49 +467,49 @@ public:
return *this; return *this;
} }
void swap(shared_count & r) // nothrow void swap(shared_count & r) BOOST_SP_NOEXCEPT
{ {
sp_counted_base * tmp = r.pi_; sp_counted_base * tmp = r.pi_;
r.pi_ = pi_; r.pi_ = pi_;
pi_ = tmp; pi_ = tmp;
} }
long use_count() const // nothrow long use_count() const BOOST_SP_NOEXCEPT
{ {
return pi_ != 0? pi_->use_count(): 0; return pi_ != 0? pi_->use_count(): 0;
} }
bool unique() const // nothrow bool unique() const BOOST_SP_NOEXCEPT
{ {
return use_count() == 1; return use_count() == 1;
} }
bool empty() const // nothrow bool empty() const BOOST_SP_NOEXCEPT
{ {
return pi_ == 0; return pi_ == 0;
} }
friend inline bool operator==(shared_count const & a, shared_count const & b) friend inline bool operator==(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT
{ {
return a.pi_ == b.pi_; return a.pi_ == b.pi_;
} }
friend inline bool operator<(shared_count const & a, shared_count const & b) friend inline bool operator<(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT
{ {
return std::less<sp_counted_base *>()( a.pi_, b.pi_ ); return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
} }
void * get_deleter( sp_typeinfo const & ti ) const void * get_deleter( sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
{ {
return pi_? pi_->get_deleter( ti ): 0; return pi_? pi_->get_deleter( ti ): 0;
} }
void * get_local_deleter( sp_typeinfo const & ti ) const void * get_local_deleter( sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
{ {
return pi_? pi_->get_local_deleter( ti ): 0; return pi_? pi_->get_local_deleter( ti ): 0;
} }
void * get_untyped_deleter() const void * get_untyped_deleter() const BOOST_SP_NOEXCEPT
{ {
return pi_? pi_->get_untyped_deleter(): 0; return pi_? pi_->get_untyped_deleter(): 0;
} }
@@ -529,14 +530,14 @@ private:
public: public:
BOOST_CONSTEXPR weak_count(): pi_(0) // nothrow BOOST_CONSTEXPR weak_count() BOOST_SP_NOEXCEPT: pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id) , id_(weak_count_id)
#endif #endif
{ {
} }
weak_count(shared_count const & r): pi_(r.pi_) // nothrow weak_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id) , id_(weak_count_id)
#endif #endif
@@ -544,7 +545,7 @@ public:
if(pi_ != 0) pi_->weak_add_ref(); if(pi_ != 0) pi_->weak_add_ref();
} }
weak_count(weak_count const & r): pi_(r.pi_) // nothrow weak_count(weak_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id) , id_(weak_count_id)
#endif #endif
@@ -556,7 +557,7 @@ public:
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
weak_count(weak_count && r): pi_(r.pi_) // nothrow weak_count(weak_count && r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id) , id_(weak_count_id)
#endif #endif
@@ -566,7 +567,7 @@ public:
#endif #endif
~weak_count() // nothrow ~weak_count() /*BOOST_SP_NOEXCEPT*/
{ {
if(pi_ != 0) pi_->weak_release(); if(pi_ != 0) pi_->weak_release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
@@ -574,7 +575,7 @@ public:
#endif #endif
} }
weak_count & operator= (shared_count const & r) // nothrow weak_count & operator= (shared_count const & r) BOOST_SP_NOEXCEPT
{ {
sp_counted_base * tmp = r.pi_; sp_counted_base * tmp = r.pi_;
@@ -588,7 +589,7 @@ public:
return *this; return *this;
} }
weak_count & operator= (weak_count const & r) // nothrow weak_count & operator= (weak_count const & r) BOOST_SP_NOEXCEPT
{ {
sp_counted_base * tmp = r.pi_; sp_counted_base * tmp = r.pi_;
@@ -602,29 +603,29 @@ public:
return *this; return *this;
} }
void swap(weak_count & r) // nothrow void swap(weak_count & r) BOOST_SP_NOEXCEPT
{ {
sp_counted_base * tmp = r.pi_; sp_counted_base * tmp = r.pi_;
r.pi_ = pi_; r.pi_ = pi_;
pi_ = tmp; pi_ = tmp;
} }
long use_count() const // nothrow long use_count() const BOOST_SP_NOEXCEPT
{ {
return pi_ != 0? pi_->use_count(): 0; return pi_ != 0? pi_->use_count(): 0;
} }
bool empty() const // nothrow bool empty() const BOOST_SP_NOEXCEPT
{ {
return pi_ == 0; return pi_ == 0;
} }
friend inline bool operator==(weak_count const & a, weak_count const & b) friend inline bool operator==(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT
{ {
return a.pi_ == b.pi_; return a.pi_ == b.pi_;
} }
friend inline bool operator<(weak_count const & a, weak_count const & b) friend inline bool operator<(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT
{ {
return std::less<sp_counted_base *>()(a.pi_, b.pi_); return std::less<sp_counted_base *>()(a.pi_, b.pi_);
} }
@@ -641,7 +642,7 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
} }
} }
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ ) inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_SP_NOEXCEPT: pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id) , id_(shared_count_id)
#endif #endif

View File

@@ -16,6 +16,7 @@
// http://www.boost.org/LICENSE_1_0.txt // http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/sp_typeinfo.hpp> #include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
@@ -27,17 +28,17 @@ namespace detail
typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t; typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
inline void atomic_increment( atomic_int_least32_t * pw ) inline void atomic_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
{ {
__c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED ); __c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
} }
inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
{ {
return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL ); return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
} }
inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
{ {
// long r = *pw; // long r = *pw;
// if( r != 0 ) ++*pw; // if( r != 0 ) ++*pw;
@@ -76,43 +77,43 @@ private:
public: public:
sp_counted_base() sp_counted_base() BOOST_SP_NOEXCEPT
{ {
__c11_atomic_init( &use_count_, 1 ); __c11_atomic_init( &use_count_, 1 );
__c11_atomic_init( &weak_count_, 1 ); __c11_atomic_init( &weak_count_, 1 );
} }
virtual ~sp_counted_base() // nothrow virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/
{ {
} }
// dispose() is called when use_count_ drops to zero, to release // dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this. // the resources managed by *this.
virtual void dispose() = 0; // nothrow virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow
// destroy() is called when weak_count_ drops to zero. // destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow virtual void destroy() BOOST_SP_NOEXCEPT // nothrow
{ {
delete this; delete this;
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() = 0; virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() void add_ref_copy() BOOST_SP_NOEXCEPT
{ {
atomic_increment( &use_count_ ); atomic_increment( &use_count_ );
} }
bool add_ref_lock() // true on success bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success
{ {
return atomic_conditional_increment( &use_count_ ) != 0; return atomic_conditional_increment( &use_count_ ) != 0;
} }
void release() // nothrow void release() BOOST_SP_NOEXCEPT
{ {
if( atomic_decrement( &use_count_ ) == 1 ) if( atomic_decrement( &use_count_ ) == 1 )
{ {
@@ -121,12 +122,12 @@ public:
} }
} }
void weak_add_ref() // nothrow void weak_add_ref() BOOST_SP_NOEXCEPT
{ {
atomic_increment( &weak_count_ ); atomic_increment( &weak_count_ );
} }
void weak_release() // nothrow void weak_release() BOOST_SP_NOEXCEPT
{ {
if( atomic_decrement( &weak_count_ ) == 1 ) if( atomic_decrement( &weak_count_ ) == 1 )
{ {
@@ -134,7 +135,7 @@ public:
} }
} }
long use_count() const // nothrow long use_count() const BOOST_SP_NOEXCEPT
{ {
return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE ); return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE );
} }

View File

@@ -19,6 +19,7 @@
// //
#include <boost/detail/sp_typeinfo.hpp> #include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
@@ -40,43 +41,43 @@ private:
public: public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 )
{ {
} }
virtual ~sp_counted_base() // nothrow virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/
{ {
} }
// dispose() is called when use_count_ drops to zero, to release // dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this. // the resources managed by *this.
virtual void dispose() = 0; // nothrow virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow
// destroy() is called when weak_count_ drops to zero. // destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow virtual void destroy() BOOST_SP_NOEXCEPT // nothrow
{ {
delete this; delete this;
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() = 0; virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() void add_ref_copy() BOOST_SP_NOEXCEPT
{ {
++use_count_; ++use_count_;
} }
bool add_ref_lock() // true on success bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success
{ {
if( use_count_ == 0 ) return false; if( use_count_ == 0 ) return false;
++use_count_; ++use_count_;
return true; return true;
} }
void release() // nothrow void release() BOOST_SP_NOEXCEPT
{ {
if( --use_count_ == 0 ) if( --use_count_ == 0 )
{ {
@@ -85,12 +86,12 @@ public:
} }
} }
void weak_add_ref() // nothrow void weak_add_ref() BOOST_SP_NOEXCEPT
{ {
++weak_count_; ++weak_count_;
} }
void weak_release() // nothrow void weak_release() BOOST_SP_NOEXCEPT
{ {
if( --weak_count_ == 0 ) if( --weak_count_ == 0 )
{ {
@@ -98,7 +99,7 @@ public:
} }
} }
long use_count() const // nothrow long use_count() const BOOST_SP_NOEXCEPT
{ {
return use_count_; return use_count_;
} }

View File

@@ -16,6 +16,7 @@
// http://www.boost.org/LICENSE_1_0.txt // http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/sp_typeinfo.hpp> #include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <atomic> #include <atomic>
#include <cstdint> #include <cstdint>
@@ -26,17 +27,17 @@ namespace boost
namespace detail namespace detail
{ {
inline void atomic_increment( std::atomic_int_least32_t * pw ) inline void atomic_increment( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
{ {
pw->fetch_add( 1, std::memory_order_relaxed ); pw->fetch_add( 1, std::memory_order_relaxed );
} }
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
{ {
return pw->fetch_sub( 1, std::memory_order_acq_rel ); return pw->fetch_sub( 1, std::memory_order_acq_rel );
} }
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
{ {
// long r = *pw; // long r = *pw;
// if( r != 0 ) ++*pw; // if( r != 0 ) ++*pw;
@@ -70,41 +71,41 @@ private:
public: public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 )
{ {
} }
virtual ~sp_counted_base() // nothrow virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/
{ {
} }
// dispose() is called when use_count_ drops to zero, to release // dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this. // the resources managed by *this.
virtual void dispose() = 0; // nothrow virtual void dispose() BOOST_SP_NOEXCEPT = 0;
// destroy() is called when weak_count_ drops to zero. // destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow virtual void destroy() BOOST_SP_NOEXCEPT
{ {
delete this; delete this;
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() = 0; virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() void add_ref_copy() BOOST_SP_NOEXCEPT
{ {
atomic_increment( &use_count_ ); atomic_increment( &use_count_ );
} }
bool add_ref_lock() // true on success bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success
{ {
return atomic_conditional_increment( &use_count_ ) != 0; return atomic_conditional_increment( &use_count_ ) != 0;
} }
void release() // nothrow void release() BOOST_SP_NOEXCEPT
{ {
if( atomic_decrement( &use_count_ ) == 1 ) if( atomic_decrement( &use_count_ ) == 1 )
{ {
@@ -113,12 +114,12 @@ public:
} }
} }
void weak_add_ref() // nothrow void weak_add_ref() BOOST_SP_NOEXCEPT
{ {
atomic_increment( &weak_count_ ); atomic_increment( &weak_count_ );
} }
void weak_release() // nothrow void weak_release() BOOST_SP_NOEXCEPT
{ {
if( atomic_decrement( &weak_count_ ) == 1 ) if( atomic_decrement( &weak_count_ ) == 1 )
{ {
@@ -126,7 +127,7 @@ public:
} }
} }
long use_count() const // nothrow long use_count() const BOOST_SP_NOEXCEPT
{ {
return use_count_.load( std::memory_order_acquire ); return use_count_.load( std::memory_order_acquire );
} }

View File

@@ -26,6 +26,7 @@
#include <boost/checked_delete.hpp> #include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_counted_base.hpp> #include <boost/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/core/addressof.hpp> #include <boost/core/addressof.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
@@ -55,12 +56,12 @@ namespace detail
template<class D> class local_sp_deleter; template<class D> class local_sp_deleter;
template<class D> D * get_local_deleter( D * /*p*/ ) template<class D> D * get_local_deleter( D * /*p*/ ) BOOST_SP_NOEXCEPT
{ {
return 0; return 0;
} }
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ); template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT;
// //
@@ -84,7 +85,7 @@ public:
#endif #endif
} }
virtual void dispose() // nothrow virtual void dispose() BOOST_SP_NOEXCEPT
{ {
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
@@ -92,17 +93,17 @@ public:
boost::checked_delete( px_ ); boost::checked_delete( px_ );
} }
virtual void * get_deleter( sp_typeinfo const & ) virtual void * get_deleter( sp_typeinfo const & ) BOOST_SP_NOEXCEPT
{ {
return 0; return 0;
} }
virtual void * get_local_deleter( sp_typeinfo const & ) virtual void * get_local_deleter( sp_typeinfo const & ) BOOST_SP_NOEXCEPT
{ {
return 0; return 0;
} }
virtual void * get_untyped_deleter() virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
{ {
return 0; return 0;
} }
@@ -167,22 +168,22 @@ public:
{ {
} }
virtual void dispose() // nothrow virtual void dispose() BOOST_SP_NOEXCEPT
{ {
del( ptr ); del( ptr );
} }
virtual void * get_deleter( sp_typeinfo const & ti ) virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
{ {
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0; return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
} }
virtual void * get_local_deleter( sp_typeinfo const & ti ) virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
{ {
return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0; return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
} }
virtual void * get_untyped_deleter() virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
{ {
return &reinterpret_cast<char&>( del ); return &reinterpret_cast<char&>( del );
} }
@@ -241,12 +242,12 @@ public:
{ {
} }
virtual void dispose() // nothrow virtual void dispose() BOOST_SP_NOEXCEPT
{ {
d_( p_ ); d_( p_ );
} }
virtual void destroy() // nothrow virtual void destroy() BOOST_SP_NOEXCEPT
{ {
#if !defined( BOOST_NO_CXX11_ALLOCATOR ) #if !defined( BOOST_NO_CXX11_ALLOCATOR )
@@ -265,17 +266,17 @@ public:
a2.deallocate( this, 1 ); a2.deallocate( this, 1 );
} }
virtual void * get_deleter( sp_typeinfo const & ti ) virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
{ {
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0; return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
} }
virtual void * get_local_deleter( sp_typeinfo const & ti ) virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
{ {
return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0; return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
} }
virtual void * get_untyped_deleter() virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
{ {
return &reinterpret_cast<char&>( d_ ); return &reinterpret_cast<char&>( d_ );
} }

View File

@@ -16,6 +16,7 @@
// //
#include <boost/smart_ptr/detail/yield_k.hpp> #include <boost/smart_ptr/detail/yield_k.hpp>
#include <boost/config.hpp>
#include <atomic> #include <atomic>
namespace boost namespace boost
@@ -32,12 +33,12 @@ public:
public: public:
bool try_lock() bool try_lock() BOOST_NOEXCEPT
{ {
return !v_.test_and_set( std::memory_order_acquire ); return !v_.test_and_set( std::memory_order_acquire );
} }
void lock() void lock() BOOST_NOEXCEPT
{ {
for( unsigned k = 0; !try_lock(); ++k ) for( unsigned k = 0; !try_lock(); ++k )
{ {
@@ -45,7 +46,7 @@ public:
} }
} }
void unlock() void unlock() BOOST_NOEXCEPT
{ {
v_ .clear( std::memory_order_release ); v_ .clear( std::memory_order_release );
} }
@@ -63,12 +64,12 @@ public:
public: public:
explicit scoped_lock( spinlock & sp ): sp_( sp ) explicit scoped_lock( spinlock & sp ) BOOST_NOEXCEPT: sp_( sp )
{ {
sp.lock(); sp.lock();
} }
~scoped_lock() ~scoped_lock() /*BOOST_NOEXCEPT*/
{ {
sp_.unlock(); sp_.unlock();
} }

View File

@@ -78,7 +78,7 @@ namespace detail
#endif // !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME #endif // !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
inline void yield( unsigned k ) inline void yield( unsigned k ) BOOST_NOEXCEPT
{ {
if( k < 4 ) if( k < 4 )
{ {

View File

@@ -1,6 +1,6 @@
/* /*
Copyright 2017 Peter Dimov Copyright 2017 Peter Dimov
Copyright 2017 Glen Joseph Fernandes Copyright 2017-2019 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -14,7 +14,8 @@ Distributed under the Boost Software License, Version 1.0.
namespace boost { namespace boost {
template<class T> template<class T>
inline typename detail::lsp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared() make_local_shared()
{ {
return boost::allocate_local_shared<T>(std::allocator<typename return boost::allocate_local_shared<T>(std::allocator<typename
@@ -22,15 +23,17 @@ make_local_shared()
} }
template<class T> template<class T>
inline typename detail::lsp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value,
make_local_shared(const typename detail::sp_array_element<T>::type& value) local_shared_ptr<T> >::type
make_local_shared(const typename remove_extent<T>::type& value)
{ {
return boost::allocate_local_shared<T>(std::allocator<typename return boost::allocate_local_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), value); detail::sp_array_scalar<T>::type>(), value);
} }
template<class T> template<class T>
inline typename detail::lsp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared(std::size_t size) make_local_shared(std::size_t size)
{ {
return boost::allocate_local_shared<T>(std::allocator<typename return boost::allocate_local_shared<T>(std::allocator<typename
@@ -38,27 +41,30 @@ make_local_shared(std::size_t size)
} }
template<class T> template<class T>
inline typename detail::lsp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared(std::size_t size, make_local_shared(std::size_t size,
const typename detail::sp_array_element<T>::type& value) const typename remove_extent<T>::type& value)
{ {
return boost::allocate_local_shared<T>(std::allocator<typename return boost::allocate_local_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size, value); detail::sp_array_scalar<T>::type>(), size, value);
} }
template<class T> template<class T>
inline typename detail::lsp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared_noinit() make_local_shared_noinit()
{ {
return allocate_local_shared_noinit<T>(std::allocator<typename return boost::allocate_local_shared_noinit<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>()); detail::sp_array_scalar<T>::type>());
} }
template<class T> template<class T>
inline typename detail::lsp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared_noinit(std::size_t size) make_local_shared_noinit(std::size_t size)
{ {
return allocate_local_shared_noinit<T>(std::allocator<typename return boost::allocate_local_shared_noinit<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size); detail::sp_array_scalar<T>::type>(), size);
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2012-2017 Glen Joseph Fernandes Copyright 2012-2019 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -13,7 +13,7 @@ Distributed under the Boost Software License, Version 1.0.
namespace boost { namespace boost {
template<class T> template<class T>
inline typename detail::sp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared() make_shared()
{ {
return boost::allocate_shared<T>(std::allocator<typename return boost::allocate_shared<T>(std::allocator<typename
@@ -21,15 +21,15 @@ make_shared()
} }
template<class T> template<class T>
inline typename detail::sp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared(const typename detail::sp_array_element<T>::type& value) make_shared(const typename remove_extent<T>::type& value)
{ {
return boost::allocate_shared<T>(std::allocator<typename return boost::allocate_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), value); detail::sp_array_scalar<T>::type>(), value);
} }
template<class T> template<class T>
inline typename detail::sp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared(std::size_t size) make_shared(std::size_t size)
{ {
return boost::allocate_shared<T>(std::allocator<typename return boost::allocate_shared<T>(std::allocator<typename
@@ -37,27 +37,26 @@ make_shared(std::size_t size)
} }
template<class T> template<class T>
inline typename detail::sp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared(std::size_t size, make_shared(std::size_t size, const typename remove_extent<T>::type& value)
const typename detail::sp_array_element<T>::type& value)
{ {
return boost::allocate_shared<T>(std::allocator<typename return boost::allocate_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size, value); detail::sp_array_scalar<T>::type>(), size, value);
} }
template<class T> template<class T>
inline typename detail::sp_if_size_array<T>::type inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared_noinit() make_shared_noinit()
{ {
return allocate_shared_noinit<T>(std::allocator<typename return boost::allocate_shared_noinit<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>()); detail::sp_array_scalar<T>::type>());
} }
template<class T> template<class T>
inline typename detail::sp_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared_noinit(std::size_t size) make_shared_noinit(std::size_t size)
{ {
return allocate_shared_noinit<T>(std::allocator<typename return boost::allocate_shared_noinit<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size); detail::sp_array_scalar<T>::type>(), size);
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2012-2015 Glen Joseph Fernandes Copyright 2012-2019 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -8,59 +8,18 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP #ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP #define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#include <boost/config.hpp> #include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_unbounded_array.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <memory> #include <memory>
#include <utility> #include <utility>
namespace boost { namespace boost {
namespace detail {
template<class T> template<class T>
struct up_if_object { inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
typedef std::unique_ptr<T> type;
};
template<class T>
struct up_if_object<T[]> { };
template<class T, std::size_t N>
struct up_if_object<T[N]> { };
template<class T>
struct up_if_array { };
template<class T>
struct up_if_array<T[]> {
typedef std::unique_ptr<T[]> type;
};
template<class T>
struct up_remove_reference {
typedef T type;
};
template<class T>
struct up_remove_reference<T&> {
typedef T type;
};
template<class T>
struct up_remove_reference<T&&> {
typedef T type;
};
template<class T>
struct up_element { };
template<class T>
struct up_element<T[]> {
typedef T type;
};
} /* detail */
template<class T>
inline typename detail::up_if_object<T>::type
make_unique() make_unique()
{ {
return std::unique_ptr<T>(new T()); return std::unique_ptr<T>(new T());
@@ -68,7 +27,7 @@ make_unique()
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class... Args> template<class T, class... Args>
inline typename detail::up_if_object<T>::type inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
make_unique(Args&&... args) make_unique(Args&&... args)
{ {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
@@ -76,33 +35,33 @@ make_unique(Args&&... args)
#endif #endif
template<class T> template<class T>
inline typename detail::up_if_object<T>::type inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
make_unique(typename detail::up_remove_reference<T>::type&& value) make_unique(typename remove_reference<T>::type&& value)
{ {
return std::unique_ptr<T>(new T(std::move(value))); return std::unique_ptr<T>(new T(std::move(value)));
} }
template<class T> template<class T>
inline typename detail::up_if_object<T>::type inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
make_unique_noinit() make_unique_noinit()
{ {
return std::unique_ptr<T>(new T); return std::unique_ptr<T>(new T);
} }
template<class T> template<class T>
inline typename detail::up_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value,
std::unique_ptr<T> >::type
make_unique(std::size_t size) make_unique(std::size_t size)
{ {
return std::unique_ptr<T>(new typename return std::unique_ptr<T>(new typename remove_extent<T>::type[size]());
detail::up_element<T>::type[size]());
} }
template<class T> template<class T>
inline typename detail::up_if_array<T>::type inline typename enable_if_<is_unbounded_array<T>::value,
std::unique_ptr<T> >::type
make_unique_noinit(std::size_t size) make_unique_noinit(std::size_t size)
{ {
return std::unique_ptr<T>(new typename return std::unique_ptr<T>(new typename remove_extent<T>::type[size]);
detail::up_element<T>::type[size]);
} }
} /* boost */ } /* boost */

View File

@@ -797,7 +797,7 @@ public:
return px == r.px && pn == r.pn; return px == r.px && pn == r.pn;
} }
boost::detail::shared_count _internal_count() const BOOST_NOEXCEPT boost::detail::shared_count _internal_count() const BOOST_SP_NOEXCEPT
{ {
return pn; return pn;
} }
@@ -1022,7 +1022,7 @@ private:
public: public:
esft2_deleter_wrapper() esft2_deleter_wrapper() BOOST_SP_NOEXCEPT
{ {
} }