diff options
Diffstat (limited to 'boost/smart_ptr')
21 files changed, 1202 insertions, 1141 deletions
diff --git a/boost/smart_ptr/allocate_shared_array.hpp b/boost/smart_ptr/allocate_shared_array.hpp index 1ae5cc7832..b43b43d575 100644 --- a/boost/smart_ptr/allocate_shared_array.hpp +++ b/boost/smart_ptr/allocate_shared_array.hpp @@ -1,181 +1,1026 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +Copyright 2012-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_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP -#include <boost/smart_ptr/detail/array_count_impl.hpp> -#include <boost/smart_ptr/detail/sp_if_array.hpp> +#include <boost/smart_ptr/shared_ptr.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 { - template<class T, class A> - inline typename boost::detail::sp_if_array<T>::type - allocate_shared(const A& allocator, std::size_t size) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef boost::detail::ms_init_tag R1; - typedef boost::detail::as_allocator<A, T, R1> A1; - typedef boost::detail::ms_in_allocator_tag D1; - std::size_t n1 = size * boost::detail::array_total<T1>::size; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(allocator, size, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); +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> +struct sp_array_scalar { + typedef T type; +}; + +template<class T, std::size_t N> +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 { + enum { + value = 1 + }; +}; + +template<class T, std::size_t N> +struct sp_array_count<T[N]> { + enum { + value = N * sp_array_count<T>::value + }; +}; + +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 + }; +}; + #if !defined(BOOST_NO_CXX11_ALLOCATOR) - boost::detail::as_init(allocator, p2, n1); +template<class A, class T> +struct sp_bind_allocator { + typedef typename std::allocator_traits<A>::template + rebind_alloc<T> type; +}; #else - boost::detail::ms_init(p2, n1); +template<class A, class T> +struct sp_bind_allocator { + typedef typename A::template rebind<T>::other type; +}; #endif - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } - - template<class T, class A> - inline typename boost::detail::sp_if_size_array<T>::type - allocate_shared(const A& allocator) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef boost::detail::ms_init_tag R1; - typedef boost::detail::as_allocator<A, T, R1> A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total<T>::size - }; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(allocator, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); + +template<bool, class = void> +struct sp_enable { }; + +template<class T> +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<class T> +inline +typename sp_enable<!boost::has_trivial_destructor<T>::value>::type +sp_array_destroy(T* storage, std::size_t size) +{ + while (size > 0) { + storage[--size].~T(); + } +} + #if !defined(BOOST_NO_CXX11_ALLOCATOR) - boost::detail::as_init(allocator, p2, N); +template<class A, class T> +inline void +sp_array_destroy(A& allocator, T* storage, std::size_t size) +{ + while (size > 0) { + std::allocator_traits<A>::destroy(allocator, &storage[--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) +{ + 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_construct(T* storage, std::size_t size) +{ + std::size_t i = 0; + try { + for (; i < size; ++i) { + ::new(static_cast<void*>(storage + i)) T(); + } + } catch (...) { + while (i > 0) { + storage[--i].~T(); + } + throw; + } +} + +template<class T> +inline void +sp_array_construct(T* storage, 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]); + } + } catch (...) { + while (i > 0) { + storage[--i].~T(); + } + throw; + } +} #else - boost::detail::ms_init(p2, N); +template<class T> +inline void +sp_array_construct(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 void +sp_array_construct(T* storage, 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]); + } +} #endif - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } - - template<class T, class A> - inline typename boost::detail::sp_if_array<T>::type - allocate_shared(const A& allocator, std::size_t size, - const typename boost::detail::array_inner<T>::type& value) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef const T2 T3; - typedef boost::detail::ms_init_tag R1; - typedef boost::detail::as_allocator<A, T, R1> A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - M = boost::detail::array_total<T1>::size - }; - std::size_t n1 = M * size; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = reinterpret_cast<T3*>(&value); - D1 d1; - A1 a1(allocator, size, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); + #if !defined(BOOST_NO_CXX11_ALLOCATOR) - boost::detail::as_init<T2, A, M>(allocator, p2, n1, p3); +#if !defined(BOOST_NO_EXCEPTIONS) +template<class A, class T> +inline void +sp_array_construct(A& allocator, T* storage, std::size_t size) +{ + std::size_t i = 0; + try { + for (i = 0; i < size; ++i) { + std::allocator_traits<A>::construct(allocator, storage + i); + } + } catch (...) { + sp_array_destroy(allocator, storage, 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) +{ + std::size_t i = 0; + try { + for (i = 0; i < size; ++i) { + std::allocator_traits<A>::construct(allocator, storage + i, + list[i % count]); + } + } catch (...) { + sp_array_destroy(allocator, storage, i); + throw; + } +} #else - boost::detail::ms_init<T2, M>(p2, n1, p3); +template<class A, class T> +inline void +sp_array_construct(A& allocator, T* storage, std::size_t size) +{ + for (std::size_t i = 0; i < size; ++i) { + std::allocator_traits<A>::construct(allocator, storage + 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) +{ + for (std::size_t i = 0; i < size; ++i) { + std::allocator_traits<A>::construct(allocator, storage + i, + list[i % count]); + } +} +#endif #endif - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } - - template<class T, class A> - inline typename boost::detail::sp_if_size_array<T>::type - allocate_shared(const A& allocator, - const typename boost::detail::array_inner<T>::type& value) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef const T2 T3; - typedef boost::detail::ms_init_tag R1; - typedef boost::detail::as_allocator<A, T, R1> A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total<T>::size, - M = boost::detail::array_total<T1>::size - }; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = reinterpret_cast<T3*>(&value); - D1 d1; - A1 a1(allocator, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); + +template<class T> +inline +typename sp_enable<boost::has_trivial_constructor<T>::value>::type +sp_array_default(T*, std::size_t) BOOST_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) +{ + std::size_t i = 0; + try { + for (; i < size; ++i) { + ::new(static_cast<void*>(storage + i)) T; + } + } catch (...) { + while (i > 0) { + storage[--i].~T(); + } + 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) +{ + for (std::size_t i = 0; i < size; ++i) { + ::new(static_cast<void*>(storage + 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) - boost::detail::as_init<T2, A, M>(allocator, p2, N, p3); +template<class T, std::size_t N, class A> +class sp_size_array_destroyer { +public: + template<class U> + static void operator_fn(U) BOOST_NOEXCEPT { } + + template<class U> + sp_size_array_destroyer(const U& allocator) BOOST_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 { + return allocator_; + } + + std::size_t size() const BOOST_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; + +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) { } + + 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); + } + + 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 { + return allocator_; + } + + std::size_t size() const BOOST_NOEXCEPT { + return size_; + } + +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 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 A, class T> +struct sp_select_deleter { + typedef sp_array_destroyer<T, + typename sp_bind_allocator<A, T>::type> type; +}; + +template<class U, class T> +struct sp_select_deleter<std::allocator<U>, T> { + typedef sp_array_deleter<T> type; +}; #else - boost::detail::ms_init<T2, M>(p2, N, p3); +template<class, class T, std::size_t N> +struct sp_select_size_deleter { + typedef sp_size_array_deleter<T, N> type; +}; + +template<class, class T> +struct sp_select_deleter { + typedef sp_array_deleter<T> type; +}; +#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; + +private: + typedef sp_counted_impl_pda<P, deleter_type, A> type; + typedef typename sp_bind_allocator<A, type>::type deallocator; + +public: + sp_counted_impl_pda(P, const deleter_type&, const A& allocator) + : deleter_(allocator), + allocator_(allocator) { } + + sp_counted_impl_pda(P, const A& allocator) + : deleter_(allocator) { } + + void dispose() { + deleter_(0); + } + + void destroy() { + deallocator allocator(allocator_); + this->~type(); + allocator.deallocate(this, 1); + } + + void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast<char&>(deleter_); + } + + void* get_untyped_deleter() { + return &reinterpret_cast<char&>(deleter_); + } + +private: + deleter_type deleter_; + A allocator_; +}; + +#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; + +private: + typedef sp_counted_impl_pda<P, deleter_type, A> type; + typedef typename sp_bind_allocator<A, type>::type deallocator; + +public: + sp_counted_impl_pda(P, const deleter_type&, const A& allocator) + : deleter_(allocator) { } + + sp_counted_impl_pda(P, const A& allocator) + : deleter_(allocator) { } + + void dispose() { + deleter_(0); + } + + void destroy() { + deallocator allocator(deleter_.allocator()); + this->~type(); + allocator.deallocate(this, 1); + } + + void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast<char&>(deleter_); + } + + void* get_untyped_deleter() { + return &reinterpret_cast<char&>(deleter_); + } + +private: + deleter_type deleter_; +}; #endif - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } - - template<class T, class A> - inline typename boost::detail::sp_if_array<T>::type - allocate_shared_noinit(const A& allocator, std::size_t size) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef boost::detail::ms_noinit_tag R1; - typedef boost::detail::as_allocator<A, T, R1> A1; - typedef boost::detail::ms_in_allocator_tag D1; - std::size_t n1 = size * boost::detail::array_total<T1>::size; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(allocator, size, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_noinit(p2, n1); - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } - - template<class T, class A> - inline typename boost::detail::sp_if_size_array<T>::type - allocate_shared_noinit(const A& allocator) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef boost::detail::ms_noinit_tag R1; - typedef boost::detail::as_allocator<A, T, R1> A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total<T>::size - }; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(allocator, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_noinit(p2, N); - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); + +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()) { } + + void dispose() { + deleter_(0); + } + + void destroy() { + deallocator allocator(allocator_, deleter_.size()); + this->~type(); + allocator.deallocate(this, 1); + } + + void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast<char&>(deleter_); + } + + void* get_untyped_deleter() { + return &reinterpret_cast<char&>(deleter_); + } + +private: + deleter_type deleter_; + A allocator_; +}; + +#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; + +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); + } + + void destroy() { + deallocator allocator(deleter_.allocator(), deleter_.size()); + this->~type(); + allocator.deallocate(this, 1); + } + + void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast<char&>(deleter_); + } + + void* get_untyped_deleter() { + return &reinterpret_cast<char&>(deleter_); } + +private: + deleter_type deleter_; +}; +#endif + +} /* detail */ + +template<class T, class A> +inline typename detail::sp_if_size_array<T>::type +allocate_shared(const A& allocator) +{ + 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)); +} + +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) +{ + 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)); +} + +template<class T, class A> +inline typename detail::sp_if_size_array<T>::type +allocate_shared_noinit(const A& allocator) +{ + 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)); } +template<class T, class A> +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_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)); +} + +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) +{ + 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), + reinterpret_cast<const scalar*>(&value), + detail::sp_array_count<type>::value); + return shared_ptr<T>(result, static_cast<type*>(start)); +} + +template<class T, class A> +inline typename detail::sp_if_array<T>::type +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 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)); +} + +} /* boost */ + #endif diff --git a/boost/smart_ptr/detail/array_allocator.hpp b/boost/smart_ptr/detail/array_allocator.hpp deleted file mode 100644 index 71479967bc..0000000000 --- a/boost/smart_ptr/detail/array_allocator.hpp +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP - -#include <boost/align/align.hpp> -#include <boost/smart_ptr/detail/array_traits.hpp> -#include <boost/smart_ptr/detail/array_utility.hpp> -#include <boost/type_traits/alignment_of.hpp> - -namespace boost { - namespace detail { - struct ms_init_tag { }; - struct ms_noinit_tag { }; - - template<class T> - struct ms_allocator_state; - - template<class T> - struct ms_allocator_state<T[]> { - typedef typename array_base<T>::type type; - - ms_allocator_state(std::size_t size_, - type** result_) - : size(size_ * array_total<T>::size), - result(result_) { - } - - std::size_t size; - - union { - type** result; - type* object; - }; - }; - - template<class T, std::size_t N> - struct ms_allocator_state<T[N]> { - typedef typename array_base<T>::type type; - - ms_allocator_state(type** result_) - : result(result_) { - } - - enum { - size = array_total<T[N]>::size - }; - - union { - type** result; - type* object; - }; - }; - - template<class A, class T, class R> - class as_allocator - : public A { - template<class A_, class T_, class R_> - friend class as_allocator; - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef std::allocator_traits<A> AT; - typedef typename AT::template rebind_alloc<char> CA; - typedef typename AT::template rebind_traits<char> CT; -#else - typedef typename A::template rebind<char>::other CA; -#endif - - public: - typedef A allocator_type; - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename AT::value_type value_type; - typedef typename AT::pointer pointer; - typedef typename AT::const_pointer const_pointer; - typedef typename AT::void_pointer void_pointer; - typedef typename AT::const_void_pointer const_void_pointer; - typedef typename AT::size_type size_type; - typedef typename AT::difference_type difference_type; -#else - typedef typename A::value_type value_type; - typedef typename A::pointer pointer; - typedef typename A::const_pointer const_pointer; - typedef typename A::size_type size_type; - typedef typename A::difference_type difference_type; - typedef typename A::reference reference; - typedef typename A::const_reference const_reference; - typedef void* void_pointer; - typedef const void* const_void_pointer; -#endif - - template<class U> - struct rebind { -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef as_allocator<typename AT:: - template rebind_alloc<U>, T, R> other; -#else - typedef as_allocator<typename A:: - template rebind<U>::other, T, R> other; -#endif - }; - - typedef typename array_base<T>::type type; - - as_allocator(const A& allocator_, type** result) - : A(allocator_), - data(result) { - } - - as_allocator(const A& allocator_, std::size_t size, - type** result) - : A(allocator_), - data(size, result) { - } - - template<class U> - as_allocator(const as_allocator<U, T, R>& other) - : A(other.allocator()), - data(other.data) { - } - - pointer allocate(size_type count, const_void_pointer = 0) { - enum { - M = boost::alignment_of<type>::value - }; - std::size_t n1 = count * sizeof(value_type); - std::size_t n2 = data.size * sizeof(type); - std::size_t n3 = n2 + M; - CA ca(allocator()); - void* p1 = ca.allocate(n1 + n3); - void* p2 = static_cast<char*>(p1) + n1; - (void)boost::alignment::align(M, n2, p2, n3); - *data.result = static_cast<type*>(p2); - return static_cast<value_type*>(p1); - } - - void deallocate(pointer memory, size_type count) { - enum { - M = boost::alignment_of<type>::value - }; - std::size_t n1 = count * sizeof(value_type); - std::size_t n2 = data.size * sizeof(type) + M; - char* p1 = reinterpret_cast<char*>(memory); - CA ca(allocator()); - ca.deallocate(p1, n1 + n2); - } - - const A& allocator() const { - return static_cast<const A&>(*this); - } - - A& allocator() { - return static_cast<A&>(*this); - } - - void set(type* memory) { - data.object = memory; - } - - void operator()() { - if (data.object) { - R tag; - release(tag); - } - } - - private: - void release(ms_init_tag) { -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - as_destroy(allocator(), data.object, data.size); -#else - ms_destroy(data.object, data.size); -#endif - } - - void release(ms_noinit_tag) { - ms_destroy(data.object, data.size); - } - - ms_allocator_state<T> data; - }; - - template<class A1, class A2, class T, class R> - bool operator==(const as_allocator<A1, T, R>& a1, - const as_allocator<A2, T, R>& a2) { - return a1.allocator() == a2.allocator(); - } - - template<class A1, class A2, class T, class R> - bool operator!=(const as_allocator<A1, T, R>& a1, - const as_allocator<A2, T, R>& a2) { - return a1.allocator() != a2.allocator(); - } - - template<class T, class Y = char> - class ms_allocator; - - template<class T, class Y> - class ms_allocator { - template<class T_, class Y_> - friend class ms_allocator; - - public: - typedef typename array_base<T>::type type; - - typedef Y value_type; - typedef Y* pointer; - typedef const Y* const_pointer; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef Y& reference; - typedef const Y& const_reference; - - template<class U> - struct rebind { - typedef ms_allocator<T, U> other; - }; - - ms_allocator(type** result) - : data(result) { - } - - ms_allocator(std::size_t size, type** result) - : data(size, result) { - } - - template<class U> - ms_allocator(const ms_allocator<T, U>& other) - : data(other.data) { - } - - pointer allocate(size_type count, const void* = 0) { - enum { - M = boost::alignment_of<type>::value - }; - std::size_t n1 = count * sizeof(Y); - std::size_t n2 = data.size * sizeof(type); - std::size_t n3 = n2 + M; - void* p1 = ::operator new(n1 + n3); - void* p2 = static_cast<char*>(p1) + n1; - (void)boost::alignment::align(M, n2, p2, n3); - *data.result = static_cast<type*>(p2); - return static_cast<Y*>(p1); - } - - void deallocate(pointer memory, size_type) { - void* p1 = memory; - ::operator delete(p1); - } - -#if defined(BOOST_NO_CXX11_ALLOCATOR) - pointer address(reference value) const { - return &value; - } - - const_pointer address(const_reference value) const { - return &value; - } - - size_type max_size() const { - enum { - N = static_cast<std::size_t>(-1) / sizeof(Y) - }; - return N; - } - - void construct(pointer memory, const_reference value) { - void* p1 = memory; - ::new(p1) Y(value); - } - - void destroy(pointer memory) { - (void)memory; - memory->~Y(); - } -#endif - - void set(type* memory) { - data.object = memory; - } - - void operator()() { - if (data.object) { - ms_destroy(data.object, data.size); - } - } - - private: - ms_allocator_state<T> data; - }; - - template<class T, class Y1, class Y2> - bool operator==(const ms_allocator<T, Y1>&, - const ms_allocator<T, Y2>&) { - return true; - } - - template<class T, class Y1, class Y2> - bool operator!=(const ms_allocator<T, Y1>&, - const ms_allocator<T, Y2>&) { - return false; - } - - class ms_in_allocator_tag { - public: - void operator()(const void*) { - } - }; - } -} - -#endif diff --git a/boost/smart_ptr/detail/array_count_impl.hpp b/boost/smart_ptr/detail/array_count_impl.hpp deleted file mode 100644 index b7c9617f0b..0000000000 --- a/boost/smart_ptr/detail/array_count_impl.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP - -#include <boost/smart_ptr/detail/array_allocator.hpp> -#include <boost/smart_ptr/detail/sp_counted_impl.hpp> - -namespace boost { - namespace detail { - template<class P, class A> - class sp_counted_impl_pda<P, ms_in_allocator_tag, A> - : public sp_counted_base { - typedef ms_in_allocator_tag D; - typedef sp_counted_impl_pda<P, D, A> Y; - public: - sp_counted_impl_pda(P, D, const A& allocator_) - : allocator(allocator_) { - } - - virtual void dispose() { - allocator(); - } - - virtual void destroy() { -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename std::allocator_traits<A>:: - template rebind_alloc<Y> YA; - typedef typename std::allocator_traits<A>:: - template rebind_traits<Y> YT; -#else - typedef typename A::template rebind<Y>::other YA; -#endif - YA a1(allocator); -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - YT::destroy(a1, this); - YT::deallocate(a1, this, 1); -#else - this->~Y(); - a1.deallocate(this, 1); -#endif - } - - virtual void* get_deleter(const sp_typeinfo&) { - return &reinterpret_cast<char&>(allocator); - } - - virtual void* get_untyped_deleter() { - return &reinterpret_cast<char&>(allocator); - } - - private: - sp_counted_impl_pda(const sp_counted_impl_pda&); - sp_counted_impl_pda& operator=(const sp_counted_impl_pda&); - - A allocator; - }; - } -} - -#endif diff --git a/boost/smart_ptr/detail/array_traits.hpp b/boost/smart_ptr/detail/array_traits.hpp deleted file mode 100644 index 819c5ba619..0000000000 --- a/boost/smart_ptr/detail/array_traits.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP - -#include <boost/type_traits/remove_cv.hpp> - -namespace boost { - namespace detail { - template<class T> - struct array_base { - typedef typename boost::remove_cv<T>::type type; - }; - - template<class T> - struct array_base<T[]> { - typedef typename array_base<T>::type type; - }; - - template<class T, std::size_t N> - struct array_base<T[N]> { - typedef typename array_base<T>::type type; - }; - - template<class T> - struct array_total { - enum { - size = 1 - }; - }; - - template<class T, std::size_t N> - struct array_total<T[N]> { - enum { - size = N * array_total<T>::size - }; - }; - - template<class T> - struct array_inner; - - template<class T> - struct array_inner<T[]> { - typedef T type; - }; - - template<class T, std::size_t N> - struct array_inner<T[N]> { - typedef T type; - }; - } -} - -#endif diff --git a/boost/smart_ptr/detail/array_utility.hpp b/boost/smart_ptr/detail/array_utility.hpp deleted file mode 100644 index 84029a1d77..0000000000 --- a/boost/smart_ptr/detail/array_utility.hpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP - -#include <boost/config.hpp> -#include <boost/type_traits/has_trivial_constructor.hpp> -#include <boost/type_traits/has_trivial_destructor.hpp> -#if !defined(BOOST_NO_CXX11_ALLOCATOR) -#include <memory> -#endif - -namespace boost { - namespace detail { - typedef boost::true_type ms_is_trivial; - typedef boost::false_type ms_no_trivial; - - template<class T> - inline void ms_destroy(T*, std::size_t, ms_is_trivial) { - } - - template<class T> - inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) { - for (std::size_t i = size; i > 0;) { - memory[--i].~T(); - } - } - - template<class T> - inline void ms_destroy(T* memory, std::size_t size) { - boost::has_trivial_destructor<T> trivial; - ms_destroy(memory, size, trivial); - } - - template<class T> - inline void ms_init(T* memory, std::size_t size, ms_is_trivial) { - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } - } - - template<class T> - inline void ms_init(T* memory, std::size_t size, ms_no_trivial) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } - } catch (...) { - ms_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } -#endif - } - - template<class T> - inline void ms_init(T* memory, std::size_t size) { - boost::has_trivial_default_constructor<T> trivial; - ms_init(memory, size, trivial); - } - - template<class T, std::size_t N> - inline void ms_init(T* memory, std::size_t size, const T* list) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % N]); - } - } catch (...) { - ms_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % N]); - } -#endif - } - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - template<class T, class A> - inline void as_destroy(const A& allocator, T* memory, - std::size_t size) { - typedef typename std::allocator_traits<A>:: - template rebind_alloc<T> TA; - typedef typename std::allocator_traits<A>:: - template rebind_traits<T> TT; - TA a2(allocator); - for (std::size_t i = size; i > 0;) { - TT::destroy(a2, &memory[--i]); - } - } - - template<class T, class A> - inline void as_init(const A& allocator, T* memory, std::size_t size, - ms_is_trivial) { - typedef typename std::allocator_traits<A>:: - template rebind_alloc<T> TA; - typedef typename std::allocator_traits<A>:: - template rebind_traits<T> TT; - TA a2(allocator); - for (std::size_t i = 0; i < size; i++) { - TT::construct(a2, memory + i); - } - } - - template<class T, class A> - inline void as_init(const A& allocator, T* memory, std::size_t size, - ms_no_trivial) { - typedef typename std::allocator_traits<A>:: - template rebind_alloc<T> TA; - typedef typename std::allocator_traits<A>:: - template rebind_traits<T> TT; - TA a2(allocator); -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - TT::construct(a2, memory + i); - } - } catch (...) { - as_destroy(a2, memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - TT::construct(a2, memory + i); - } -#endif - } - - template<class T, class A> - inline void as_init(const A& allocator, T* memory, std::size_t size) { - boost::has_trivial_default_constructor<T> trivial; - as_init(allocator, memory, size, trivial); - } - - template<class T, class A, std::size_t N> - inline void as_init(const A& allocator, T* memory, std::size_t size, - const T* list) { - typedef typename std::allocator_traits<A>:: - template rebind_alloc<T> TA; - typedef typename std::allocator_traits<A>:: - template rebind_traits<T> TT; - TA a2(allocator); -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - TT::construct(a2, memory + i, list[i % N]); - } - } catch (...) { - as_destroy(a2, memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - TT::construct(a2, memory + i, list[i % N]); - } -#endif - } -#endif - - template<class T> - inline void ms_noinit(T*, std::size_t, ms_is_trivial) { - } - - template<class T> - inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T; - } - } catch (...) { - ms_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T; - } -#endif - } - - template<class T> - inline void ms_noinit(T* memory, std::size_t size) { - boost::has_trivial_default_constructor<T> trivial; - ms_noinit(memory, size, trivial); - } - } -} - -#endif diff --git a/boost/smart_ptr/detail/shared_count.hpp b/boost/smart_ptr/detail/shared_count.hpp index 7996aa4325..9813842300 100644 --- a/boost/smart_ptr/detail/shared_count.hpp +++ b/boost/smart_ptr/detail/shared_count.hpp @@ -249,18 +249,8 @@ public: try { -#if !defined( BOOST_NO_CXX11_ALLOCATOR ) - - impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 ); - pi_ = pi; - std::allocator_traits<A2>::construct( a2, pi, p, d, a ); - -#else - - pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + pi_ = a2.allocate( 1 ); ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); - -#endif } catch(...) { @@ -276,28 +266,11 @@ public: #else -#if !defined( BOOST_NO_CXX11_ALLOCATOR ) - - impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 ); - pi_ = pi; - -#else - - pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); - -#endif + pi_ = a2.allocate( 1 ); if( pi_ != 0 ) { -#if !defined( BOOST_NO_CXX11_ALLOCATOR ) - - std::allocator_traits<A2>::construct( a2, pi, p, d, a ); - -#else - ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); - -#endif } else { @@ -333,18 +306,8 @@ public: try { -#if !defined( BOOST_NO_CXX11_ALLOCATOR ) - - impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 ); - pi_ = pi; - std::allocator_traits<A2>::construct( a2, pi, p, a ); - -#else - - pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + pi_ = a2.allocate( 1 ); ::new( static_cast< void* >( pi_ ) ) impl_type( p, a ); - -#endif } catch(...) { @@ -360,28 +323,11 @@ public: #else -#if !defined( BOOST_NO_CXX11_ALLOCATOR ) - - impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 ); - pi_ = pi; - -#else - - pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); - -#endif + pi_ = a2.allocate( 1 ); if( pi_ != 0 ) { -#if !defined( BOOST_NO_CXX11_ALLOCATOR ) - - std::allocator_traits<A2>::construct( a2, pi, p, a ); - -#else - ::new( static_cast< void* >( pi_ ) ) impl_type( p, a ); - -#endif } else { diff --git a/boost/smart_ptr/detail/sp_counted_base.hpp b/boost/smart_ptr/detail/sp_counted_base.hpp index 83ede23173..438613765b 100644 --- a/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/boost/smart_ptr/detail/sp_counted_base.hpp @@ -20,7 +20,7 @@ #include <boost/config.hpp> #include <boost/smart_ptr/detail/sp_has_sync.hpp> -#if defined( __clang__ ) && defined( __has_extension ) +#if !defined( __c2__ ) && defined( __clang__ ) && defined( __has_extension ) # if __has_extension( __c_atomic__ ) # define BOOST_SP_HAS_CLANG_C11_ATOMICS # endif diff --git a/boost/smart_ptr/detail/sp_counted_impl.hpp b/boost/smart_ptr/detail/sp_counted_impl.hpp index 1222f3c9f4..b29769e3af 100644 --- a/boost/smart_ptr/detail/sp_counted_impl.hpp +++ b/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -236,16 +236,8 @@ public: A2 a2( a_ ); -#if !defined( BOOST_NO_CXX11_ALLOCATOR ) - - std::allocator_traits<A2>::destroy( a2, this ); - -#else - this->~this_type(); -#endif - a2.deallocate( this, 1 ); } diff --git a/boost/smart_ptr/detail/sp_has_sync.hpp b/boost/smart_ptr/detail/sp_has_sync.hpp index 16de21d379..e1debf0cc9 100644 --- a/boost/smart_ptr/detail/sp_has_sync.hpp +++ b/boost/smart_ptr/detail/sp_has_sync.hpp @@ -22,15 +22,15 @@ #ifndef BOOST_SP_NO_SYNC -#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) +#if !defined( __c2__ ) && defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) # define BOOST_SP_HAS_SYNC -#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) +#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ ) # define BOOST_SP_HAS_SYNC -#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) +#elif !defined( __c2__ ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) #define BOOST_SP_HAS_SYNC diff --git a/boost/smart_ptr/detail/sp_if_array.hpp b/boost/smart_ptr/detail/sp_if_array.hpp deleted file mode 100644 index 9a2c1e0baa..0000000000 --- a/boost/smart_ptr/detail/sp_if_array.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP -#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP - -#include <boost/smart_ptr/shared_ptr.hpp> - -namespace boost { - namespace detail { - template<class T> - struct sp_if_array; - - template<class T> - struct sp_if_array<T[]> { - typedef boost::shared_ptr<T[]> type; - }; - - template<class T> - 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; - }; - } -} - -#endif diff --git a/boost/smart_ptr/detail/sp_noexcept.hpp b/boost/smart_ptr/detail/sp_noexcept.hpp new file mode 100644 index 0000000000..6818dce38d --- /dev/null +++ b/boost/smart_ptr/detail/sp_noexcept.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_noexcept.hpp +// +// Copyright 2016 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include <boost/config.hpp> + +#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1700 && BOOST_MSVC < 1900 + +#define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW + +#else + +#define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED diff --git a/boost/smart_ptr/enable_shared_from_this.hpp b/boost/smart_ptr/enable_shared_from_this.hpp index 4e3f243d28..642403a0a3 100644 --- a/boost/smart_ptr/enable_shared_from_this.hpp +++ b/boost/smart_ptr/enable_shared_from_this.hpp @@ -15,6 +15,7 @@ #include <boost/smart_ptr/weak_ptr.hpp> #include <boost/smart_ptr/shared_ptr.hpp> +#include <boost/smart_ptr/detail/sp_noexcept.hpp> #include <boost/assert.hpp> #include <boost/config.hpp> @@ -25,20 +26,20 @@ template<class T> class enable_shared_from_this { protected: - enable_shared_from_this() BOOST_NOEXCEPT + enable_shared_from_this() BOOST_SP_NOEXCEPT { } - enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT + enable_shared_from_this(enable_shared_from_this const &) BOOST_SP_NOEXCEPT { } - enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT + enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_SP_NOEXCEPT { return *this; } - ~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw + ~enable_shared_from_this() BOOST_SP_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw { } diff --git a/boost/smart_ptr/intrusive_ptr.hpp b/boost/smart_ptr/intrusive_ptr.hpp index 1e9339732b..0e46212165 100644 --- a/boost/smart_ptr/intrusive_ptr.hpp +++ b/boost/smart_ptr/intrusive_ptr.hpp @@ -19,6 +19,7 @@ #include <boost/detail/workaround.hpp> #include <boost/smart_ptr/detail/sp_convertible.hpp> #include <boost/smart_ptr/detail/sp_nullptr_t.hpp> +#include <boost/smart_ptr/detail/sp_noexcept.hpp> #include <boost/config/no_tr1/functional.hpp> // for std::less @@ -59,7 +60,7 @@ public: typedef T element_type; - BOOST_CONSTEXPR intrusive_ptr() BOOST_NOEXCEPT : px( 0 ) + BOOST_CONSTEXPR intrusive_ptr() BOOST_SP_NOEXCEPT : px( 0 ) { } @@ -111,12 +112,12 @@ public: #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px ) + intrusive_ptr(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT : px( rhs.px ) { rhs.px = 0; } - intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT + intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT { this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this); return *this; diff --git a/boost/smart_ptr/make_shared_array.hpp b/boost/smart_ptr/make_shared_array.hpp index c48f5070b6..2eaf4db71b 100644 --- a/boost/smart_ptr/make_shared_array.hpp +++ b/boost/smart_ptr/make_shared_array.hpp @@ -1,158 +1,66 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +Copyright 2012-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_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP -#include <boost/smart_ptr/detail/array_count_impl.hpp> -#include <boost/smart_ptr/detail/sp_if_array.hpp> +#include <boost/smart_ptr/allocate_shared_array.hpp> namespace boost { - template<class T> - inline typename boost::detail::sp_if_array<T>::type - make_shared(std::size_t size) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef boost::detail::ms_allocator<T> A1; - typedef boost::detail::ms_in_allocator_tag D1; - std::size_t n1 = size * boost::detail::array_total<T1>::size; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(size, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_init(p2, n1); - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } - template<class T> - inline typename boost::detail::sp_if_size_array<T>::type - make_shared() { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef boost::detail::ms_allocator<T> A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total<T>::size - }; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(&p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_init(p2, N); - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } +template<class T> +inline typename detail::sp_if_size_array<T>::type +make_shared() +{ + return boost::allocate_shared<T>(std::allocator<typename + detail::sp_array_scalar<T>::type>()); +} + +template<class T> +inline typename detail::sp_if_size_array<T>::type +make_shared(const typename detail::sp_array_element<T>::type& value) +{ + return boost::allocate_shared<T>(std::allocator<typename + detail::sp_array_scalar<T>::type>(), value); +} - template<class T> - inline typename boost::detail::sp_if_array<T>::type - make_shared(std::size_t size, - const typename boost::detail::array_inner<T>::type& value) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef const T2 T3; - typedef boost::detail::ms_allocator<T> A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - M = boost::detail::array_total<T1>::size - }; - std::size_t n1 = M * size; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = reinterpret_cast<T3*>(&value); - D1 d1; - A1 a1(size, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_init<T2, M>(p2, n1, p3); - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } +template<class T> +inline typename detail::sp_if_array<T>::type +make_shared(std::size_t size) +{ + return boost::allocate_shared<T>(std::allocator<typename + detail::sp_array_scalar<T>::type>(), size); +} - template<class T> - inline typename boost::detail::sp_if_size_array<T>::type - make_shared(const typename boost::detail::array_inner<T>::type& value) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef const T2 T3; - typedef boost::detail::ms_allocator<T> A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - M = boost::detail::array_total<T1>::size, - N = boost::detail::array_total<T>::size - }; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = reinterpret_cast<T3*>(&value); - D1 d1; - A1 a1(&p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_init<T2, M>(p2, N, p3); - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } +template<class T> +inline typename detail::sp_if_array<T>::type +make_shared(std::size_t size, + const typename detail::sp_array_element<T>::type& value) +{ + return boost::allocate_shared<T>(std::allocator<typename + detail::sp_array_scalar<T>::type>(), size, value); +} - template<class T> - inline typename boost::detail::sp_if_array<T>::type - make_shared_noinit(std::size_t size) { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef boost::detail::ms_allocator<T> A1; - typedef boost::detail::ms_in_allocator_tag D1; - std::size_t n1 = size * boost::detail::array_total<T1>::size; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(size, &p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_noinit(p2, n1); - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } +template<class T> +inline typename detail::sp_if_size_array<T>::type +make_shared_noinit() +{ + return allocate_shared_noinit<T>(std::allocator<typename + detail::sp_array_scalar<T>::type>()); +} - template<class T> - inline typename boost::detail::sp_if_size_array<T>::type - make_shared_noinit() { - typedef typename boost::detail::array_inner<T>::type T1; - typedef typename boost::detail::array_base<T1>::type T2; - typedef boost::detail::ms_allocator<T> A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total<T>::size - }; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(&p2); - shared_ptr<T> s1(p1, d1, a1); - A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_noinit(p2, N); - a2->set(p2); - p1 = reinterpret_cast<T1*>(p2); - return shared_ptr<T>(s1, p1); - } +template<class T> +inline typename detail::sp_if_array<T>::type +make_shared_noinit(std::size_t size) +{ + return allocate_shared_noinit<T>(std::allocator<typename + detail::sp_array_scalar<T>::type>(), size); } +} /* boost */ + #endif diff --git a/boost/smart_ptr/make_unique.hpp b/boost/smart_ptr/make_unique.hpp index d054e3dfe1..eed503392b 100644 --- a/boost/smart_ptr/make_unique.hpp +++ b/boost/smart_ptr/make_unique.hpp @@ -1,10 +1,9 @@ /* -(c) 2014-2015 Glen Joseph Fernandes -<glenjofe -at- gmail.com> +Copyright 2012-2015 Glen Joseph Fernandes +(glenjofe@gmail.com) -Distributed under the Boost Software -License, Version 1.0. -http://boost.org/LICENSE_1_0.txt +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP #define BOOST_SMART_PTR_MAKE_UNIQUE_HPP @@ -15,6 +14,7 @@ http://boost.org/LICENSE_1_0.txt namespace boost { namespace detail { + template<class T> struct up_if_object { typedef std::unique_ptr<T> type; @@ -56,10 +56,12 @@ template<class T> struct up_element<T[]> { typedef T type; }; + } /* detail */ template<class T> -inline typename detail::up_if_object<T>::type make_unique() +inline typename detail::up_if_object<T>::type +make_unique() { return std::unique_ptr<T>(new T()); } @@ -67,7 +69,7 @@ inline typename detail::up_if_object<T>::type make_unique() #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template<class T, class... Args> inline typename detail::up_if_object<T>::type - make_unique(Args&&... args) +make_unique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } @@ -75,31 +77,34 @@ inline typename detail::up_if_object<T>::type template<class T> inline typename detail::up_if_object<T>::type - make_unique(typename detail::up_remove_reference<T>::type&& value) +make_unique(typename detail::up_remove_reference<T>::type&& value) { return std::unique_ptr<T>(new T(std::move(value))); } template<class T> -inline typename detail::up_if_object<T>::type make_unique_noinit() +inline typename detail::up_if_object<T>::type +make_unique_noinit() { return std::unique_ptr<T>(new T); } template<class T> -inline typename detail::up_if_array<T>::type make_unique(std::size_t n) +inline typename detail::up_if_array<T>::type +make_unique(std::size_t size) { - return std::unique_ptr<T>(new - typename detail::up_element<T>::type[n]()); + return std::unique_ptr<T>(new typename + detail::up_element<T>::type[size]()); } template<class T> inline typename detail::up_if_array<T>::type - make_unique_noinit(std::size_t n) +make_unique_noinit(std::size_t size) { - return std::unique_ptr<T>(new - typename detail::up_element<T>::type[n]); + return std::unique_ptr<T>(new typename + detail::up_element<T>::type[size]); } + } /* boost */ #endif diff --git a/boost/smart_ptr/owner_less.hpp b/boost/smart_ptr/owner_less.hpp index 6899325bd6..75d182c121 100644 --- a/boost/smart_ptr/owner_less.hpp +++ b/boost/smart_ptr/owner_less.hpp @@ -5,6 +5,7 @@ // owner_less.hpp // // Copyright (c) 2008 Frank Mori Hess +// Copyright (c) 2016 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,44 +14,20 @@ // See http://www.boost.org/libs/smart_ptr/smart_ptr.htm for documentation. // -#include <functional> - namespace boost { - template<typename T> class shared_ptr; - template<typename T> class weak_ptr; - - namespace detail - { - template<typename T, typename U> - struct generic_owner_less : public std::binary_function<T, T, bool> - { - bool operator()(const T &lhs, const T &rhs) const - { - return lhs.owner_before(rhs); - } - bool operator()(const T &lhs, const U &rhs) const - { - return lhs.owner_before(rhs); - } - bool operator()(const U &lhs, const T &rhs) const - { - return lhs.owner_before(rhs); - } - }; - } // namespace detail - template<typename T> struct owner_less; - - template<typename T> - struct owner_less<shared_ptr<T> >: - public detail::generic_owner_less<shared_ptr<T>, weak_ptr<T> > - {}; +template<class T = void> struct owner_less +{ + typedef bool result_type; + typedef T first_argument_type; + typedef T second_argument_type; - template<typename T> - struct owner_less<weak_ptr<T> >: - public detail::generic_owner_less<weak_ptr<T>, shared_ptr<T> > - {}; + template<class U, class V> bool operator()( U const & u, V const & v ) const + { + return u.owner_before( v ); + } +}; } // namespace boost diff --git a/boost/smart_ptr/scoped_array.hpp b/boost/smart_ptr/scoped_array.hpp index e395e28f85..f847c094e4 100644 --- a/boost/smart_ptr/scoped_array.hpp +++ b/boost/smart_ptr/scoped_array.hpp @@ -15,6 +15,7 @@ #include <boost/assert.hpp> #include <boost/checked_delete.hpp> #include <boost/smart_ptr/detail/sp_nullptr_t.hpp> +#include <boost/smart_ptr/detail/sp_noexcept.hpp> #include <boost/detail/workaround.hpp> @@ -54,7 +55,7 @@ public: typedef T element_type; - explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p ) + explicit scoped_array( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p ) { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_array_constructor_hook( px ); diff --git a/boost/smart_ptr/scoped_ptr.hpp b/boost/smart_ptr/scoped_ptr.hpp index d5d8720f52..8fd8a180fb 100644 --- a/boost/smart_ptr/scoped_ptr.hpp +++ b/boost/smart_ptr/scoped_ptr.hpp @@ -16,6 +16,7 @@ #include <boost/checked_delete.hpp> #include <boost/smart_ptr/detail/sp_nullptr_t.hpp> #include <boost/smart_ptr/detail/sp_disable_deprecated.hpp> +#include <boost/smart_ptr/detail/sp_noexcept.hpp> #include <boost/detail/workaround.hpp> #ifndef BOOST_NO_AUTO_PTR @@ -62,7 +63,7 @@ public: typedef T element_type; - explicit scoped_ptr( T * p = 0 ): px( p ) // never throws + explicit scoped_ptr( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_constructor_hook( px ); diff --git a/boost/smart_ptr/shared_array.hpp b/boost/smart_ptr/shared_array.hpp index fd58071be0..2e5cb134a3 100644 --- a/boost/smart_ptr/shared_array.hpp +++ b/boost/smart_ptr/shared_array.hpp @@ -24,6 +24,7 @@ #include <boost/smart_ptr/shared_ptr.hpp> #include <boost/smart_ptr/detail/shared_count.hpp> #include <boost/smart_ptr/detail/sp_nullptr_t.hpp> +#include <boost/smart_ptr/detail/sp_noexcept.hpp> #include <boost/detail/workaround.hpp> #include <cstddef> // for std::ptrdiff_t @@ -53,13 +54,13 @@ public: typedef T element_type; - shared_array() BOOST_NOEXCEPT : px( 0 ), pn() + shared_array() BOOST_SP_NOEXCEPT : px( 0 ), pn() { } #if !defined( BOOST_NO_CXX11_NULLPTR ) - shared_array( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() + shared_array( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn() { } @@ -95,11 +96,11 @@ public: // ... except in C++0x, move disables the implicit copy - shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + shared_array( shared_array const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn ) { } - shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn() + shared_array( shared_array && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn() { pn.swap( r.pn ); r.px = 0; @@ -133,7 +134,7 @@ public: // assignment - shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT + shared_array & operator=( shared_array const & r ) BOOST_SP_NOEXCEPT { this_type( r ).swap( *this ); return *this; @@ -152,7 +153,7 @@ public: #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT + shared_array & operator=( shared_array && r ) BOOST_SP_NOEXCEPT { this_type( static_cast< shared_array && >( r ) ).swap( *this ); return *this; diff --git a/boost/smart_ptr/shared_ptr.hpp b/boost/smart_ptr/shared_ptr.hpp index 77f68bebd0..e33707b3bc 100644 --- a/boost/smart_ptr/shared_ptr.hpp +++ b/boost/smart_ptr/shared_ptr.hpp @@ -30,6 +30,7 @@ #include <boost/smart_ptr/detail/sp_convertible.hpp> #include <boost/smart_ptr/detail/sp_nullptr_t.hpp> #include <boost/smart_ptr/detail/sp_disable_deprecated.hpp> +#include <boost/smart_ptr/detail/sp_noexcept.hpp> #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) #include <boost/smart_ptr/detail/spinlock_pool.hpp> @@ -344,13 +345,13 @@ public: typedef typename boost::detail::sp_element< T >::type element_type; - shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ + shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ { } #if !defined( BOOST_NO_CXX11_NULLPTR ) - shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws + shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws { } @@ -402,7 +403,7 @@ public: // ... except in C++0x, move disables the implicit copy - shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + shared_ptr( shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn ) { } @@ -521,7 +522,7 @@ public: // assignment - shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT + shared_ptr & operator=( shared_ptr const & r ) BOOST_SP_NOEXCEPT { this_type(r).swap(*this); return *this; @@ -605,7 +606,7 @@ public: #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn() + shared_ptr( shared_ptr && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn() { pn.swap( r.pn ); r.px = 0; @@ -629,7 +630,7 @@ public: r.px = 0; } - shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT + shared_ptr & operator=( shared_ptr && r ) BOOST_SP_NOEXCEPT { this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); return *this; @@ -882,6 +883,50 @@ template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> return shared_ptr<T>( r, p ); } +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT +{ + (void) static_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr<T>::element_type E; + + E * p = static_cast< E* >( r.get() ); + 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 +{ + (void) const_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr<T>::element_type E; + + E * p = const_cast< E* >( r.get() ); + 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 +{ + (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr<T>::element_type E; + + E * p = dynamic_cast< E* >( r.get() ); + 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 +{ + (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr<T>::element_type E; + + E * p = reinterpret_cast< E* >( r.get() ); + return shared_ptr<T>( std::move(r), p ); +} + +#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + // 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 diff --git a/boost/smart_ptr/weak_ptr.hpp b/boost/smart_ptr/weak_ptr.hpp index e3e9ad9bde..f3411f7225 100644 --- a/boost/smart_ptr/weak_ptr.hpp +++ b/boost/smart_ptr/weak_ptr.hpp @@ -16,6 +16,7 @@ #include <memory> // boost.TR1 include order fix #include <boost/smart_ptr/detail/shared_count.hpp> #include <boost/smart_ptr/shared_ptr.hpp> +#include <boost/smart_ptr/detail/sp_noexcept.hpp> namespace boost { @@ -31,7 +32,7 @@ public: typedef typename boost::detail::sp_element< T >::type element_type; - weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+ + weak_ptr() BOOST_SP_NOEXCEPT : px(0), pn() // never throws in 1.30+ { } @@ -41,11 +42,11 @@ public: // ... except in C++0x, move disables the implicit copy - weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + weak_ptr( weak_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn ) { } - weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT + weak_ptr & operator=( weak_ptr const & r ) BOOST_SP_NOEXCEPT { px = r.px; pn = r.pn; @@ -106,13 +107,13 @@ public: // for better efficiency in the T == Y case weak_ptr( weak_ptr && r ) - BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) + BOOST_SP_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) { r.px = 0; } // for better efficiency in the T == Y case - weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT + weak_ptr & operator=( weak_ptr && r ) BOOST_SP_NOEXCEPT { this_type( static_cast< weak_ptr && >( r ) ).swap( *this ); return *this; |