2 Copyright 2017-2019 Glen Joseph Fernandes
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
9 #define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
11 #include <boost/smart_ptr/allocate_shared_array.hpp>
12 #include <boost/smart_ptr/local_shared_ptr.hpp>
17 class BOOST_SYMBOL_VISIBLE lsp_array_base
18 : public local_counted_base {
20 void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
21 count_ = shared_count(base);
24 virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
25 shared_count().swap(count_);
28 virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT {
38 : public sp_array_state<A> {
41 lsp_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
42 : sp_array_state<A>(other, size) { }
44 lsp_array_base& base() BOOST_SP_NOEXCEPT {
52 template<class A, std::size_t N>
53 class lsp_size_array_state
54 : public sp_size_array_state<A, N> {
57 lsp_size_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
58 : sp_size_array_state<A, N>(other, size) { }
60 lsp_array_base& base() BOOST_SP_NOEXCEPT {
70 template<class T, class A>
71 inline typename enable_if_<is_unbounded_array<T>::value,
72 local_shared_ptr<T> >::type
73 allocate_local_shared(const A& allocator, std::size_t count)
75 typedef typename detail::sp_array_element<T>::type element;
76 typedef typename detail::sp_bind_allocator<A, element>::type other;
77 typedef detail::lsp_array_state<other> state;
78 typedef detail::sp_array_base<state> base;
79 detail::sp_array_result<other, base> result(allocator, count);
80 base* node = result.get();
81 element* start = detail::sp_array_start<element>(node);
82 ::new(static_cast<void*>(node)) base(allocator, start, count);
83 detail::lsp_array_base& local = node->state().base();
86 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
90 template<class T, class A>
91 inline typename enable_if_<is_bounded_array<T>::value,
92 local_shared_ptr<T> >::type
93 allocate_local_shared(const A& allocator)
96 count = extent<T>::value
98 typedef typename detail::sp_array_element<T>::type element;
99 typedef typename detail::sp_bind_allocator<A, element>::type other;
100 typedef detail::lsp_size_array_state<other, count> state;
101 typedef detail::sp_array_base<state> base;
102 detail::sp_array_result<other, base> result(allocator, count);
103 base* node = result.get();
104 element* start = detail::sp_array_start<element>(node);
105 ::new(static_cast<void*>(node)) base(allocator, start, count);
106 detail::lsp_array_base& local = node->state().base();
109 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
113 template<class T, class A>
114 inline typename enable_if_<is_unbounded_array<T>::value,
115 local_shared_ptr<T> >::type
116 allocate_local_shared(const A& allocator, std::size_t count,
117 const typename remove_extent<T>::type& value)
119 typedef typename detail::sp_array_element<T>::type element;
120 typedef typename detail::sp_bind_allocator<A, element>::type other;
121 typedef detail::lsp_array_state<other> state;
122 typedef detail::sp_array_base<state> base;
123 detail::sp_array_result<other, base> result(allocator, count);
124 base* node = result.get();
125 element* start = detail::sp_array_start<element>(node);
126 ::new(static_cast<void*>(node)) base(allocator, start, count, value);
127 detail::lsp_array_base& local = node->state().base();
130 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
134 template<class T, class A>
135 inline typename enable_if_<is_bounded_array<T>::value,
136 local_shared_ptr<T> >::type
137 allocate_local_shared(const A& allocator,
138 const typename remove_extent<T>::type& value)
141 count = extent<T>::value
143 typedef typename detail::sp_array_element<T>::type element;
144 typedef typename detail::sp_bind_allocator<A, element>::type other;
145 typedef detail::lsp_size_array_state<other, count> state;
146 typedef detail::sp_array_base<state> base;
147 detail::sp_array_result<other, base> result(allocator, count);
148 base* node = result.get();
149 element* start = detail::sp_array_start<element>(node);
150 ::new(static_cast<void*>(node)) base(allocator, start, count, value);
151 detail::lsp_array_base& local = node->state().base();
154 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
158 template<class T, class A>
159 inline typename enable_if_<is_unbounded_array<T>::value,
160 local_shared_ptr<T> >::type
161 allocate_local_shared_noinit(const A& allocator, std::size_t count)
163 return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator),
167 template<class T, class A>
168 inline typename enable_if_<is_bounded_array<T>::value,
169 local_shared_ptr<T> >::type
170 allocate_local_shared_noinit(const A& allocator)
172 return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator));