]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/allocate_local_shared_array.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / smart_ptr / allocate_local_shared_array.hpp
1 /*
2 Copyright 2017-2019 Glen Joseph Fernandes
3 (glenjofe@gmail.com)
4
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
7 */
8 #ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
9 #define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
10
11 #include <boost/smart_ptr/allocate_shared_array.hpp>
12 #include <boost/smart_ptr/local_shared_ptr.hpp>
13
14 namespace boost {
15 namespace detail {
16
17 class BOOST_SYMBOL_VISIBLE lsp_array_base
18 : public local_counted_base {
19 public:
20 void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
21 count_ = shared_count(base);
22 }
23
24 virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
25 shared_count().swap(count_);
26 }
27
28 virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT {
29 return count_;
30 }
31
32 private:
33 shared_count count_;
34 };
35
36 template<class A>
37 class lsp_array_state
38 : public sp_array_state<A> {
39 public:
40 template<class U>
41 lsp_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
42 : sp_array_state<A>(other, size) { }
43
44 lsp_array_base& base() BOOST_SP_NOEXCEPT {
45 return base_;
46 }
47
48 private:
49 lsp_array_base base_;
50 };
51
52 template<class A, std::size_t N>
53 class lsp_size_array_state
54 : public sp_size_array_state<A, N> {
55 public:
56 template<class U>
57 lsp_size_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
58 : sp_size_array_state<A, N>(other, size) { }
59
60 lsp_array_base& base() BOOST_SP_NOEXCEPT {
61 return base_;
62 }
63
64 private:
65 lsp_array_base base_;
66 };
67
68 } /* detail */
69
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)
74 {
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();
84 local.set(node);
85 result.release();
86 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
87 &local);
88 }
89
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)
94 {
95 enum {
96 count = extent<T>::value
97 };
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();
107 local.set(node);
108 result.release();
109 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
110 &local);
111 }
112
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)
118 {
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();
128 local.set(node);
129 result.release();
130 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
131 &local);
132 }
133
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)
139 {
140 enum {
141 count = extent<T>::value
142 };
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();
152 local.set(node);
153 result.release();
154 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
155 &local);
156 }
157
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)
162 {
163 return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator),
164 count);
165 }
166
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)
171 {
172 return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator));
173 }
174
175 } /* boost */
176
177 #endif