File indexing completed on 2024-11-15 09:31:07
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
0009 #define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
0010
0011 #include <boost/smart_ptr/detail/requires_cxx11.hpp>
0012 #include <boost/smart_ptr/allocate_shared_array.hpp>
0013 #include <boost/smart_ptr/local_shared_ptr.hpp>
0014
0015 namespace boost {
0016 namespace detail {
0017
0018 class BOOST_SYMBOL_VISIBLE lsp_array_base
0019 : public local_counted_base {
0020 public:
0021 void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
0022 count_ = shared_count(base);
0023 }
0024
0025 void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
0026 shared_count().swap(count_);
0027 }
0028
0029 shared_count local_cb_get_shared_count() const
0030 BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
0031 return count_;
0032 }
0033
0034 private:
0035 shared_count count_;
0036 };
0037
0038 template<class A>
0039 class lsp_array_state
0040 : public sp_array_state<A> {
0041 public:
0042 template<class U>
0043 lsp_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
0044 : sp_array_state<A>(other, size) { }
0045
0046 lsp_array_base& base() BOOST_SP_NOEXCEPT {
0047 return base_;
0048 }
0049
0050 private:
0051 lsp_array_base base_;
0052 };
0053
0054 template<class A, std::size_t N>
0055 class lsp_size_array_state
0056 : public sp_size_array_state<A, N> {
0057 public:
0058 template<class U>
0059 lsp_size_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
0060 : sp_size_array_state<A, N>(other, size) { }
0061
0062 lsp_array_base& base() BOOST_SP_NOEXCEPT {
0063 return base_;
0064 }
0065
0066 private:
0067 lsp_array_base base_;
0068 };
0069
0070 }
0071
0072 template<class T, class A>
0073 inline typename enable_if_<is_unbounded_array<T>::value,
0074 local_shared_ptr<T> >::type
0075 allocate_local_shared(const A& allocator, std::size_t count)
0076 {
0077 typedef typename detail::sp_array_element<T>::type element;
0078 typedef typename allocator_rebind<A, element>::type other;
0079 typedef detail::lsp_array_state<other> state;
0080 typedef detail::sp_array_base<state> base;
0081 detail::sp_array_result<other, base> result(allocator, count);
0082 base* node = result.get();
0083 element* start = detail::sp_array_start<element>(node);
0084 ::new(static_cast<void*>(node)) base(allocator, start, count);
0085 detail::lsp_array_base& local = node->state().base();
0086 local.set(node);
0087 result.release();
0088 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
0089 &local);
0090 }
0091
0092 template<class T, class A>
0093 inline typename enable_if_<is_bounded_array<T>::value,
0094 local_shared_ptr<T> >::type
0095 allocate_local_shared(const A& allocator)
0096 {
0097 enum {
0098 count = extent<T>::value
0099 };
0100 typedef typename detail::sp_array_element<T>::type element;
0101 typedef typename allocator_rebind<A, element>::type other;
0102 typedef detail::lsp_size_array_state<other, count> state;
0103 typedef detail::sp_array_base<state> base;
0104 detail::sp_array_result<other, base> result(allocator, count);
0105 base* node = result.get();
0106 element* start = detail::sp_array_start<element>(node);
0107 ::new(static_cast<void*>(node)) base(allocator, start, count);
0108 detail::lsp_array_base& local = node->state().base();
0109 local.set(node);
0110 result.release();
0111 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
0112 &local);
0113 }
0114
0115 template<class T, class A>
0116 inline typename enable_if_<is_unbounded_array<T>::value,
0117 local_shared_ptr<T> >::type
0118 allocate_local_shared(const A& allocator, std::size_t count,
0119 const typename remove_extent<T>::type& value)
0120 {
0121 typedef typename detail::sp_array_element<T>::type element;
0122 typedef typename allocator_rebind<A, element>::type other;
0123 typedef detail::lsp_array_state<other> state;
0124 typedef detail::sp_array_base<state> base;
0125 detail::sp_array_result<other, base> result(allocator, count);
0126 base* node = result.get();
0127 element* start = detail::sp_array_start<element>(node);
0128 ::new(static_cast<void*>(node)) base(allocator, start, count, value);
0129 detail::lsp_array_base& local = node->state().base();
0130 local.set(node);
0131 result.release();
0132 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
0133 &local);
0134 }
0135
0136 template<class T, class A>
0137 inline typename enable_if_<is_bounded_array<T>::value,
0138 local_shared_ptr<T> >::type
0139 allocate_local_shared(const A& allocator,
0140 const typename remove_extent<T>::type& value)
0141 {
0142 enum {
0143 count = extent<T>::value
0144 };
0145 typedef typename detail::sp_array_element<T>::type element;
0146 typedef typename allocator_rebind<A, element>::type other;
0147 typedef detail::lsp_size_array_state<other, count> state;
0148 typedef detail::sp_array_base<state> base;
0149 detail::sp_array_result<other, base> result(allocator, count);
0150 base* node = result.get();
0151 element* start = detail::sp_array_start<element>(node);
0152 ::new(static_cast<void*>(node)) base(allocator, start, count, value);
0153 detail::lsp_array_base& local = node->state().base();
0154 local.set(node);
0155 result.release();
0156 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
0157 &local);
0158 }
0159
0160 template<class T, class A>
0161 inline typename enable_if_<is_unbounded_array<T>::value,
0162 local_shared_ptr<T> >::type
0163 allocate_local_shared_noinit(const A& allocator, std::size_t count)
0164 {
0165 return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator),
0166 count);
0167 }
0168
0169 template<class T, class A>
0170 inline typename enable_if_<is_bounded_array<T>::value,
0171 local_shared_ptr<T> >::type
0172 allocate_local_shared_noinit(const A& allocator)
0173 {
0174 return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator));
0175 }
0176
0177 }
0178
0179 #endif