diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index bac8cef..c35a106 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -9,7 +9,7 @@ #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP -#include +#include #include #include #include @@ -24,10 +24,10 @@ namespace boost { T1* p1 = 0; T3* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1(n1); + boost::detail::as_allocator a1(allocator, n1, &p2); + boost::detail::as_deleter d1(allocator, n1); boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::as_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->init(p2); @@ -45,10 +45,10 @@ namespace boost { }; T1* p1 = 0; T3* p2 = 0; - boost::detail::allocate_array_helper a1(allocator, &p2); - boost::detail::array_deleter d1; + boost::detail::as_allocator a1(allocator, &p2); + boost::detail::as_deleter d1(allocator); boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::as_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->init(p2); @@ -70,10 +70,10 @@ namespace boost { T3* p2 = 0; T4* p3 = reinterpret_cast(&value); std::size_t n1 = M * size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1(n1); + boost::detail::as_allocator a1(allocator, n1, &p2); + boost::detail::as_deleter d1(allocator, n1); boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::as_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->template init(p2, p3); @@ -95,10 +95,10 @@ namespace boost { T1* p1 = 0; T3* p2 = 0; T4* p3 = reinterpret_cast(&value); - boost::detail::allocate_array_helper a1(allocator, &p2); - boost::detail::array_deleter d1; + boost::detail::as_allocator a1(allocator, &p2); + boost::detail::as_deleter d1(allocator); boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::as_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->template init(p2, p3); @@ -114,10 +114,10 @@ namespace boost { T1* p1 = 0; T3* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1(n1); + boost::detail::as_allocator a1(allocator, n1, &p2); + boost::detail::ms_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::ms_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->noinit(p2); @@ -135,10 +135,10 @@ namespace boost { }; T1* p1 = 0; T3* p2 = 0; - boost::detail::allocate_array_helper a1(allocator, &p2); - boost::detail::array_deleter d1; + boost::detail::as_allocator a1(allocator, &p2); + boost::detail::ms_deleter d1; boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::ms_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->noinit(p2); diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp deleted file mode 100644 index de43c76..0000000 --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp +++ /dev/null @@ -1,118 +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_ALLOCATE_ARRAY_HELPER_HPP -#define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP - -#include -#include -#include - -namespace boost { - namespace detail { - template - class allocate_array_helper - : array_size_base { - using array_size_base::size; - - template - friend class allocate_array_helper; - - typedef typename A::template rebind ::other A2; - typedef typename A::template rebind::other A3; - - public: - typedef typename array_inner::type type; - typedef typename A2::value_type value_type; - typedef typename A2::pointer pointer; - typedef typename A2::const_pointer const_pointer; - typedef typename A2::reference reference; - typedef typename A2::const_reference const_reference; - typedef typename A2::size_type size_type; - typedef typename A2::difference_type difference_type; - - template - struct rebind { - typedef allocate_array_helper other; - }; - - allocate_array_helper(const A& allocator_, type** data_) - : allocator(allocator_), - data(data_) { - } - - allocate_array_helper(const A& allocator_, std::size_t size_, type** data_) - : array_size_base(size_), - allocator(allocator_), - data(data_) { - } - - template - allocate_array_helper(const allocate_array_helper& other) - : array_size_base(other), - allocator(other.allocator), - data(other.data) { - } - - pointer address(reference value) const { - return allocator.address(value); - } - - const_pointer address(const_reference value) const { - return allocator.address(value); - } - - size_type max_size() const { - return allocator.max_size(); - } - - pointer allocate(size_type count, const void* value = 0) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(Y) + a1 - 1; - char* p1 = A3(allocator).allocate(size + n1, value); - char* p2 = p1 + n1; - while (std::size_t(p2) % a1 != 0) { - p2--; - } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); - } - - void deallocate(pointer memory, size_type count) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(Y) + a1 - 1; - char* p1 = reinterpret_cast(memory); - A3(allocator).deallocate(p1, size + n1); - } - - void construct(pointer memory, const Y& value) { - allocator.construct(memory, value); - } - - void destroy(pointer memory) { - allocator.destroy(memory); - } - - template - bool operator==(const allocate_array_helper& other) const { - return allocator == other.allocator; - } - - template - bool operator!=(const allocate_array_helper& other) const { - return !(*this == other); - } - - private: - A2 allocator; - type** data; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp new file mode 100644 index 0000000..3371545 --- /dev/null +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -0,0 +1,272 @@ +/* + * 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 +#include +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#include +#endif + +namespace boost { + namespace detail { + template + struct ms_allocator_base; + + template + struct ms_allocator_base { + ms_allocator_base(std::size_t size_) + : size(size_ * sizeof(T)) { + } + + std::size_t size; + }; + + template + struct ms_allocator_base { + enum { + size = N * sizeof(T) + }; + }; + + template + class as_allocator + : ms_allocator_base { + using ms_allocator_base::size; + + template + friend class as_allocator; + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename std::allocator_traits:: + template rebind_alloc::other YA; + + typedef typename std::allocator_traits:: + template rebind_alloc::other CA; + + typedef typename std::allocator_traits:: + template rebind_traits::other YT; + + typedef typename std::allocator_traits:: + template rebind_traits::other CT; +#else + typedef typename A::template rebind::other YA; + typedef typename A::template rebind::other CA; +#endif + + public: + typedef typename array_inner::type type; + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename YT::value_type value_type; + typedef typename YT::pointer pointer; + typedef typename YT::const_pointer const_pointer; + typedef typename YT::size_type size_type; + typedef typename YT::difference_type difference_type; + typedef Y& reference; + typedef const Y& const_reference; +#else + typedef typename YA::value_type value_type; + typedef typename YA::pointer pointer; + typedef typename YA::const_pointer const_pointer; + typedef typename YA::size_type size_type; + typedef typename YA::difference_type difference_type; + typedef typename YA::reference reference; + typedef typename YA::const_reference const_reference; +#endif + + template + struct rebind { + typedef as_allocator other; + }; + + as_allocator(const A& allocator_, type** data_) + : allocator(allocator_), + data(data_) { + } + + as_allocator(const A& allocator_, std::size_t size_, type** data_) + : ms_allocator_base(size_), + allocator(allocator_), + data(data_) { + } + + template + as_allocator(const as_allocator& other) + : ms_allocator_base(other), + allocator(other.allocator), + data(other.data) { + } + + pointer address(reference value) const { + return allocator.address(value); + } + + const_pointer address(const_reference value) const { + return allocator.address(value); + } + + size_type max_size() const { + return allocator.max_size(); + } + + pointer allocate(size_type count, const void* value = 0) { + std::size_t a1 = boost::alignment_of::value; + std::size_t n1 = count * sizeof(Y) + a1 - 1; + CA ca(allocator); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + char* p1 = CT::allocate(ca, size + n1, value); +#else + char* p1 = ca.allocate(size + n1, value); +#endif + char* p2 = p1 + n1; + while (std::size_t(p2) % a1 != 0) { + p2--; + } + *data = reinterpret_cast(p2); + return reinterpret_cast(p1); + } + + void deallocate(pointer memory, size_type count) { + std::size_t a1 = boost::alignment_of::value; + std::size_t n1 = count * sizeof(Y) + a1 - 1; + char* p1 = reinterpret_cast(memory); + CA ca(allocator); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + CT::deallocate(ca, p1, size + n1); +#else + ca.deallocate(p1, size + n1); +#endif + } + + void construct(pointer memory, const Y& value) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + YT::construct(allocator, memory, value); +#else + allocator.construct(memory, value); +#endif + } + + void destroy(pointer memory) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + YT::destroy(allocator, memory); +#else + allocator.destroy(memory); +#endif + } + + template + bool operator==(const as_allocator& other) const { + return allocator == other.allocator; + } + + template + bool operator!=(const as_allocator& other) const { + return !(*this == other); + } + + private: + YA allocator; + type** data; + }; + + template + class ms_allocator + : ms_allocator_base { + using ms_allocator_base::size; + + template + friend class ms_allocator; + + public: + typedef typename array_inner::type type; + typedef Y value_type; + typedef Y* pointer; + typedef const Y* const_pointer; + typedef std::size_t size_type; + typedef ptrdiff_t difference_type; + typedef Y& reference; + typedef const Y& const_reference; + + template + struct rebind { + typedef ms_allocator other; + }; + + ms_allocator(type** data_) + : data(data_) { + } + + ms_allocator(std::size_t size_, type** data_) + : ms_allocator_base(size_), + data(data_) { + } + + template + ms_allocator(const ms_allocator& other) + : ms_allocator_base(other), + data(other.data) { + } + + pointer address(reference value) const { + return &value; + } + + const_pointer address(const_reference value) const { + return &value; + } + + size_type max_size() const { + return static_cast(-1) / sizeof(Y); + } + + pointer allocate(size_type count, const void* = 0) { + std::size_t a1 = boost::alignment_of::value; + std::size_t n1 = count * sizeof(Y)+a1 - 1; + void* p1 = ::operator new(n1 + size); + char* p2 = static_cast(p1)+n1; + while (std::size_t(p2) % a1 != 0) { + p2--; + } + *data = reinterpret_cast(p2); + return reinterpret_cast(p1); + } + + void deallocate(pointer memory, size_type) { + void* p1 = memory; + ::operator delete(p1); + } + + void construct(pointer memory, const Y& value) { + void* p1 = memory; + ::new(p1) Y(value); + } + + void destroy(pointer memory) { + memory->~Y(); + } + + template + bool operator==(const ms_allocator&) const { + return true; + } + + template + bool operator!=(const ms_allocator& other) const { + return !(*this == other); + } + + private: + type** data; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 58adbbc..7d99795 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -9,17 +9,22 @@ #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP #define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP +#include #include -#include +#include +#include +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#include +#endif namespace boost { namespace detail { template - struct array_count_base; + struct ms_deleter_base; template - struct array_count_base { - array_count_base(std::size_t size_) + struct ms_deleter_base { + ms_deleter_base(std::size_t size_) : size(size_) { } @@ -27,61 +32,305 @@ namespace boost { }; template - struct array_count_base { + struct ms_deleter_base { enum { size = N }; }; - template - class array_deleter - : array_count_base { - using array_count_base::size; + template + class as_deleter + : ms_deleter_base { + using ms_deleter_base::size; public: typedef typename array_inner::type type; - - array_deleter() - : object(0) { - } - array_deleter(std::size_t size_) - : array_count_base(size_), +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + as_deleter(const A& allocator_) + : allocator(allocator_), object(0) { } - - ~array_deleter() { - if (object) { - array_destroy(object, size); - } +#else + as_deleter(const A&) + : object(0) { } +#endif + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + as_deleter(const A& allocator_, std::size_t size_) + : ms_deleter_base(size_), + allocator(allocator_), + object(0) { + } +#else + as_deleter(const A&, std::size_t size_) + : ms_deleter_base(size_), + object(0) { + } +#endif void init(type* memory) { - array_init(memory, size); + value_init(memory); object = memory; } template void init(type* memory, const type* value) { - array_init(memory, size, value); - object = memory; - } - - void noinit(type* memory) { - array_noinit(memory, size); + value_init(memory, value); object = memory; } void operator()(const void*) { if (object) { - array_destroy(object, size); - object = 0; + destroy(object, size); } } private: +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename std::allocator_traits:: + template rebind_alloc::other TA; + + typedef typename std::allocator_traits:: + template rebind_traits::other TT; +#endif + + void destroy(type*, std::size_t, boost::true_type) { + } + + void destroy(type* memory, std::size_t n, boost::false_type) { + for (std::size_t i = n; i > 0;) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + TT::destroy(allocator, &memory[--i]); +#else + memory[--i].~type(); +#endif + } + } + + void destroy(type* memory, std::size_t n) { + boost::has_trivial_destructor tag; + destroy(memory, n, tag); + } + + void value_init(type* memory, boost::true_type) { + for (std::size_t i = 0; i < size; i++) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + TT::construct(allocator, memory + i); +#else + void* p1 = memory + i; + ::new(p1) type(); +#endif + } + } + + void value_init(type* memory, boost::false_type) { +#if !defined(BOOST_NO_EXCEPTIONS) + std::size_t i = 0; + try { + for (; i < size; i++) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + TT::construct(allocator, memory + i); +#else + void* p1 = memory + i; + ::new(p1) type(); +#endif + } + } catch (...) { + destroy(memory, i); + throw; + } +#else + for (std::size_t i = 0; i < size; i++) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + TT::construct(allocator, memory + i); +#else + void* p1 = memory + i; + ::new(p1) type(); +#endif + } +#endif + } + + void value_init(type* memory) { + boost::has_trivial_default_constructor tag; + value_init(memory, tag); + } + + template + void value_init(type* memory, const type* list) { +#if !defined(BOOST_NO_EXCEPTIONS) + std::size_t i = 0; + try { + for (; i < size; i++) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + TT::construct(allocator, memory + i, list[i % N]); +#else + void* p1 = memory + i; + ::new(p1) type(list[i % N]); +#endif + } + } catch (...) { + destroy(memory, i); + throw; + } +#else + for (std::size_t i = 0; i < size; i++) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + TT::construct(allocator, memory + i, list[i % N]); +#else + void* p1 = memory + i; + ::new(p1) type(list[i % N]); +#endif + } +#endif + } + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + TA allocator; +#endif type* object; - }; + }; + + template + class ms_deleter + : ms_deleter_base { + using ms_deleter_base::size; + + public: + typedef typename array_inner::type type; + + ms_deleter() + : object(0) { + } + + ms_deleter(std::size_t size_) + : ms_deleter_base(size_), + object(0) { + } + + void init(type* memory) { + value_init(memory); + object = memory; + } + + template + void init(type* memory, const type* value) { + value_init(memory, value); + object = memory; + } + + void noinit(type* memory) { + default_init(memory); + object = memory; + } + + void operator()(const void*) { + if (object) { + destroy(object, size); + } + } + + private: + void destroy(type*, std::size_t, boost::true_type) { + } + + void destroy(type* memory, std::size_t n, boost::false_type) { + for (std::size_t i = n; i > 0;) { + memory[--i].~type(); + } + } + + void destroy(type* memory, std::size_t n) { + boost::has_trivial_destructor tag; + destroy(memory, n, tag); + } + + void value_init(type* memory, boost::true_type) { + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) type(); + } + } + + void value_init(type* memory, boost::false_type) { +#if !defined(BOOST_NO_EXCEPTIONS) + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) type(); + } + } catch (...) { + destroy(memory, i); + throw; + } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) type(); + } +#endif + } + + void value_init(type* memory) { + boost::has_trivial_default_constructor tag; + value_init(memory, tag); + } + + void default_init(type*, boost::true_type) { + } + + void default_init(type* memory, boost::false_type) { +#if !defined(BOOST_NO_EXCEPTIONS) + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) type; + } + } catch (...) { + destroy(memory, i); + throw; + } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) type; + } +#endif + } + + void default_init(type* memory) { + boost::has_trivial_default_constructor tag; + default_init(memory, tag); + } + + template + void value_init(type* memory, const type* list) { +#if !defined(BOOST_NO_EXCEPTIONS) + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) type(list[i % N]); + } + } catch (...) { + destroy(memory, i); + throw; + } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) type(list[i % N]); + } +#endif + } + + private: + type* object; + }; } } diff --git a/include/boost/smart_ptr/detail/array_size_base.hpp b/include/boost/smart_ptr/detail/array_size_base.hpp deleted file mode 100644 index df5aab2..0000000 --- a/include/boost/smart_ptr/detail/array_size_base.hpp +++ /dev/null @@ -1,37 +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_SIZE_BASE_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_SIZE_BASE_HPP - -#include - -namespace boost { - namespace detail { - template - struct array_size_base; - - template - struct array_size_base { - array_size_base(std::size_t size_) - : size(size_ * sizeof(T)) { - } - - std::size_t size; - }; - - template - struct array_size_base { - enum { - size = N * sizeof(T) - }; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp deleted file mode 100644 index d8444b8..0000000 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ /dev/null @@ -1,131 +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 -#include -#include - -namespace boost { - namespace detail { - template - inline void array_destroy(T*, std::size_t, - boost::true_type) { - } - - template - inline void array_destroy(T* memory, std::size_t size, - boost::false_type) { - for (std::size_t i = size; i > 0; ) { - memory[--i].~T(); - } - } - - template - inline void array_destroy(T* memory, std::size_t size) { - boost::has_trivial_destructor type; - array_destroy(memory, size, type); - } - - template - inline void array_value(T* memory, std::size_t size, - boost::true_type) { - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } - } - - template - inline void array_value(T* memory, std::size_t size, - boost::false_type) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } - } catch (...) { - array_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } -#endif - } - - template - inline void array_init(T* memory, std::size_t size) { - boost::has_trivial_default_constructor type; - array_value(memory, size, type); - } - - template - inline void array_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 (...) { - array_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 - } - - template - inline void array_default(T*, std::size_t, - boost::true_type) { - } - - template - inline void array_default(T* memory, std::size_t size, - boost::false_type) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T; - } - } catch (...) { - array_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T; - } -#endif - } - - template - inline void array_noinit(T* memory, std::size_t size) { - boost::has_trivial_default_constructor type; - array_default(memory, size, type); - } - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp deleted file mode 100644 index 3aebb6d..0000000 --- a/include/boost/smart_ptr/detail/make_array_helper.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2012-2104 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_MAKE_ARRAY_HELPER_HPP -#define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP - -#include -#include -#include - -namespace boost { - namespace detail { - template - class make_array_helper - : array_size_base { - using array_size_base::size; - - template - friend class make_array_helper; - - public: - typedef typename array_inner::type type; - typedef Y value_type; - typedef Y* pointer; - typedef const Y* const_pointer; - typedef Y& reference; - typedef const Y& const_reference; - typedef std::size_t size_type; - typedef ptrdiff_t difference_type; - - template - struct rebind { - typedef make_array_helper other; - }; - - make_array_helper(type** data_) - : data(data_) { - } - - make_array_helper(std::size_t size_, type** data_) - : array_size_base(size_), - data(data_) { - } - - template - make_array_helper(const make_array_helper& other) - : array_size_base(other), - data(other.data) { - } - - pointer address(reference value) const { - return &value; - } - - const_pointer address(const_reference value) const { - return &value; - } - - size_type max_size() const { - return static_cast(-1) / sizeof(Y); - } - - pointer allocate(size_type count, const void* = 0) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(Y) + a1 - 1; - void* p1 = ::operator new(n1 + size); - char* p2 = static_cast(p1) + n1; - while (std::size_t(p2) % a1 != 0) { - p2--; - } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); - } - - void deallocate(pointer memory, size_type) { - void* p1 = memory; - ::operator delete(p1); - } - - void construct(pointer memory, const Y& value) { - void* p1 = memory; - ::new(p1) Y(value); - } - - void destroy(pointer memory) { - memory->~Y(); - } - - template - bool operator==(const make_array_helper&) const { - return true; - } - - template - bool operator!=(const make_array_helper& other) const { - return !(*this == other); - } - - private: - type** data; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 6a0bcfd..2deba39 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -9,9 +9,8 @@ #ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP +#include #include -#include -#include #include #include @@ -25,10 +24,10 @@ namespace boost { T1* p1 = 0; T3* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1(n1); + boost::detail::ms_allocator a1(n1, &p2); + boost::detail::ms_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::ms_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->init(p2); @@ -46,10 +45,10 @@ namespace boost { }; T1* p1 = 0; T3* p2 = 0; - boost::detail::make_array_helper a1(&p2); - boost::detail::array_deleter d1; + boost::detail::ms_allocator a1(&p2); + boost::detail::ms_deleter d1; boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::ms_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->init(p2); @@ -71,10 +70,10 @@ namespace boost { T3* p2 = 0; T4* p3 = reinterpret_cast(&value); std::size_t n1 = M * size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1(n1); + boost::detail::ms_allocator a1(n1, &p2); + boost::detail::ms_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::ms_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->template init(p2, p3); @@ -95,10 +94,10 @@ namespace boost { T1* p1 = 0; T3* p2 = 0; T4* p3 = reinterpret_cast(&value); - boost::detail::make_array_helper a1(&p2); - boost::detail::array_deleter d1; + boost::detail::ms_allocator a1(&p2); + boost::detail::ms_deleter d1; boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::ms_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->template init(p2, p3); @@ -114,10 +113,10 @@ namespace boost { T1* p1 = 0; T3* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1(n1); + boost::detail::ms_allocator a1(n1, &p2); + boost::detail::ms_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::ms_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->noinit(p2); @@ -135,10 +134,10 @@ namespace boost { }; T1* p1 = 0; T3* p2 = 0; - boost::detail::make_array_helper a1(&p2); - boost::detail::array_deleter d1; + boost::detail::ms_allocator a1(&p2); + boost::detail::ms_deleter d1; boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; + typedef boost::detail::ms_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->noinit(p2); diff --git a/make_shared_array.html b/make_shared_array.html index 76e4f20..28a7a11 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -97,8 +97,6 @@ template<typename U, typename A>

Throws: bad_alloc, an exception thrown from A::allocate, or from the initialization of the object.

- -

Remarks:

This implementation performs no more than one memory @@ -115,18 +113,34 @@ template<typename U, typename A>

Array elements are initialized in ascending order of their addresses.

When a subobject of a non-array type T is specified to - be initialized to a value value, or to - T(list...), where list... is a list of - constructor arguments, make_shared shall perform this - initialization via the expression ::new(ptr) T(value) - or ::new(ptr) T(list...) respectively, where - ptr has type void* and points to storage - suitable to hold an object of type T.

+ be initialized to a value value, + make_shared shall perform this initialization via the + expression ::new(ptr) T(value), where ptr + has type void* and points to storage suitable to hold + an object of type T.

+

When a subobject of non-array type T is specified to + be initialized to a value value, + allocate_shared shall perform this initialization via + the expression allocator_traits<A2>::construct(a2, ptr, + value), where ptr points to storage suitable to + hold an object of type T and a2 of type A2 + is a rebound copy of the allocator allocator passed to + allocate_shared such that its value_type + is T.

When a subobject of non-array type T is specified to be value-initialized, make_shared shall perform this initialization via the expression ::new(ptr) T(), where ptr has type void* and points to storage suitable to hold an object of type T.

+

When a subobject of non-array type T is specified to + be value-initialized, allocate_shared shall perform + this initialization via the expression + allocator_traits<A2>::construct(a2, ptr), where + ptr points to storage suitable to hold an object + of type T and a2 of type A2 is a rebound + copy of the allocator allocator passed to + allocate_shared such that its value_type + is T.

When a subobject of non-array type T is specified to be default-initialized, make_shared_noinit and allocate_shared_noinit shall perform this @@ -138,6 +152,9 @@ template<typename U, typename A> the initialized elements should be destroyed in the reverse order of their construction.

+

Notes: These functions will typically allocate more memory + than sizeof(U) to allow for internal bookkeeping + structures such as the reference counts.

Free Functions

template<typename U> 
@@ -149,8 +166,6 @@ template<typename U, typename A>
         object of type T[size].

Remarks: These overloads shall only participate in overload resolution when U is of the form T[].

- -

Examples:

boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
@@ -166,8 +181,6 @@ template<typename U, typename A>
         object of type T[N].

Remarks: These overloads shall only participate in overload resolution when U is of the form T[N].

-
-

Examples:

boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>();
@@ -184,8 +197,6 @@ template<typename U, typename A>
         is initialized to value.

Remarks: These overloads shall only participate in overload resolution when U is of the form T[].

-
-

Examples:

boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size, 1);
@@ -202,8 +213,6 @@ template<typename U, typename A>
         initialized to value.

Remarks: These overloads shall only participate in overload resolution when U is of the form T[N].

-
-

Examples:

boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>(1);
@@ -219,8 +228,6 @@ template<typename U, typename A>
         object of type T[size].

Remarks: These overloads shall only participate in overload resolution when U is of the form T[].

-
-

Examples:

boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<int[]>(size);
@@ -236,8 +243,6 @@ template<typename U, typename A>
         object of type T[N].

Remarks: These overloads shall only participate in overload resolution when U is of the form T[N].

-
-

Examples:

boost::shared_ptr<int[8]> a1 = boost::make_shared_noinit<int[8]>();
diff --git a/make_unique.html b/make_unique.html
index fc46428..f1246db 100644
--- a/make_unique.html
+++ b/make_unique.html
@@ -56,8 +56,6 @@ template<typename U>
         r is the return value.

Throws: bad_alloc, or an exception thrown from the initialization of the object.

-
-

Remarks:

When an object of a non-array type T is specified to @@ -82,8 +80,6 @@ unique_ptr<U> make_unique(Args&&... args);

initialized to U(forward<Args>(args)...).

Remarks: This overload shall only participate in overload resolution when U is not an array type.

- -

Examples:

unique_ptr<float> p1 = boost::make_unique<float>();
@@ -97,8 +93,6 @@ unique_ptr<U> make_unique(U&& value);
initialized to move(value).

Remarks: This overload shall only participate in overload resolution when U is not an array type.

-
-

Examples:

unique_ptr<string> p1 = boost::make_unique<string>({'a', 'b'});
@@ -112,8 +106,6 @@ unique_ptr<U> make_unique(size_t size);
T[size].

Remarks: This overload shall only participate in overload resolution when U is of the form T[].

-
-

Examples:

unique_ptr<double[]> p1 = boost::make_unique<double[]>(4);
@@ -127,8 +119,6 @@ unique_ptr<U> make_unique_noinit();
type U.

Remarks: This overload shall only participate in overload resolution when U is not an array type.

-
-

Examples:

unique_ptr<float> p1 = boost::make_unique_noinit<float>();
@@ -142,8 +132,6 @@ unique_ptr<U> make_unique_noinit(size_t size);
type T[size].

Remarks: This overload shall only participate in overload resolution when U is of the form T[].

-
-

Examples:

unique_ptr<double[]> p1 = boost::make_unique_noinit<double[]>(4);