Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@101
|
3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // See http://www.boost.org/libs/container for documentation.
|
Chris@16
|
8 //
|
Chris@16
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
Chris@16
|
12 #define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
Chris@16
|
13
|
Chris@101
|
14 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
15 # include <boost/config.hpp>
|
Chris@101
|
16 #endif
|
Chris@101
|
17
|
Chris@101
|
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@16
|
19 # pragma once
|
Chris@16
|
20 #endif
|
Chris@16
|
21
|
Chris@101
|
22 #include <boost/container/detail/config_begin.hpp>
|
Chris@16
|
23 #include <boost/container/detail/workaround.hpp>
|
Chris@16
|
24
|
Chris@101
|
25 // container
|
Chris@101
|
26 #include <boost/container/allocator_traits.hpp>
|
Chris@101
|
27 // container/detail
|
Chris@101
|
28 #include <boost/container/detail/addressof.hpp>
|
Chris@101
|
29 #include <boost/container/detail/alloc_helpers.hpp>
|
Chris@101
|
30 #include <boost/container/detail/allocator_version_traits.hpp>
|
Chris@101
|
31 #include <boost/container/detail/construct_in_place.hpp>
|
Chris@101
|
32 #include <boost/container/detail/destroyers.hpp>
|
Chris@101
|
33 #include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
Chris@101
|
34 #include <boost/container/detail/mpl.hpp>
|
Chris@101
|
35 #include <boost/container/detail/placement_new.hpp>
|
Chris@101
|
36 #include <boost/container/detail/to_raw_pointer.hpp>
|
Chris@101
|
37 #include <boost/container/detail/type_traits.hpp>
|
Chris@101
|
38 #include <boost/container/detail/version_type.hpp>
|
Chris@101
|
39 // intrusive
|
Chris@101
|
40 #include <boost/intrusive/detail/mpl.hpp>
|
Chris@16
|
41 #include <boost/intrusive/options.hpp>
|
Chris@101
|
42 // move
|
Chris@101
|
43 #include <boost/move/utility_core.hpp>
|
Chris@101
|
44 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
45 #include <boost/move/detail/fwd_macros.hpp>
|
Chris@16
|
46 #endif
|
Chris@101
|
47 // other
|
Chris@101
|
48 #include <boost/core/no_exceptions_support.hpp>
|
Chris@16
|
49
|
Chris@16
|
50
|
Chris@16
|
51 namespace boost {
|
Chris@16
|
52 namespace container {
|
Chris@16
|
53 namespace container_detail {
|
Chris@16
|
54
|
Chris@101
|
55 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
|
Chris@101
|
56 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
|
Chris@16
|
57
|
Chris@101
|
58 template<class Allocator, class ICont>
|
Chris@16
|
59 struct node_alloc_holder
|
Chris@16
|
60 {
|
Chris@101
|
61 //If the intrusive container is an associative container, obtain the predicate, which will
|
Chris@101
|
62 //be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
|
Chris@101
|
63 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
|
Chris@101
|
64 value_compare, container_detail::nat) intrusive_value_compare;
|
Chris@101
|
65 //In that case obtain the value predicate from the node predicate via predicate_type
|
Chris@101
|
66 //if intrusive_value_compare is node_compare<>, nat otherwise
|
Chris@101
|
67 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare,
|
Chris@101
|
68 predicate_type, container_detail::nat) value_compare;
|
Chris@101
|
69
|
Chris@101
|
70 typedef allocator_traits<Allocator> allocator_traits_type;
|
Chris@16
|
71 typedef typename allocator_traits_type::value_type value_type;
|
Chris@101
|
72 typedef ICont intrusive_container;
|
Chris@16
|
73 typedef typename ICont::value_type Node;
|
Chris@16
|
74 typedef typename allocator_traits_type::template
|
Chris@16
|
75 portable_rebind_alloc<Node>::type NodeAlloc;
|
Chris@16
|
76 typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
|
Chris@16
|
77 typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
|
Chris@101
|
78 typedef Allocator ValAlloc;
|
Chris@16
|
79 typedef typename node_allocator_traits_type::pointer NodePtr;
|
Chris@16
|
80 typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
|
Chris@16
|
81 typedef typename node_allocator_traits_type::size_type size_type;
|
Chris@16
|
82 typedef typename node_allocator_traits_type::difference_type difference_type;
|
Chris@16
|
83 typedef container_detail::integral_constant<unsigned,
|
Chris@16
|
84 boost::container::container_detail::
|
Chris@16
|
85 version<NodeAlloc>::value> alloc_version;
|
Chris@16
|
86 typedef typename ICont::iterator icont_iterator;
|
Chris@16
|
87 typedef typename ICont::const_iterator icont_citerator;
|
Chris@16
|
88 typedef allocator_destroyer<NodeAlloc> Destroyer;
|
Chris@16
|
89 typedef allocator_traits<NodeAlloc> NodeAllocTraits;
|
Chris@16
|
90 typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
|
Chris@16
|
91
|
Chris@16
|
92 private:
|
Chris@16
|
93 BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
|
Chris@16
|
94
|
Chris@16
|
95 public:
|
Chris@16
|
96
|
Chris@16
|
97 //Constructors for sequence containers
|
Chris@16
|
98 node_alloc_holder()
|
Chris@16
|
99 : members_()
|
Chris@16
|
100 {}
|
Chris@16
|
101
|
Chris@16
|
102 explicit node_alloc_holder(const ValAlloc &a)
|
Chris@16
|
103 : members_(a)
|
Chris@16
|
104 {}
|
Chris@16
|
105
|
Chris@16
|
106 explicit node_alloc_holder(const node_alloc_holder &x)
|
Chris@16
|
107 : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
|
Chris@16
|
108 {}
|
Chris@16
|
109
|
Chris@16
|
110 explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
|
Chris@16
|
111 : members_(boost::move(x.node_alloc()))
|
Chris@16
|
112 { this->icont().swap(x.icont()); }
|
Chris@16
|
113
|
Chris@16
|
114 //Constructors for associative containers
|
Chris@101
|
115 explicit node_alloc_holder(const value_compare &c, const ValAlloc &a)
|
Chris@16
|
116 : members_(a, c)
|
Chris@16
|
117 {}
|
Chris@16
|
118
|
Chris@101
|
119 explicit node_alloc_holder(const value_compare &c, const node_alloc_holder &x)
|
Chris@16
|
120 : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
|
Chris@16
|
121 {}
|
Chris@16
|
122
|
Chris@101
|
123 explicit node_alloc_holder(const value_compare &c)
|
Chris@16
|
124 : members_(c)
|
Chris@16
|
125 {}
|
Chris@16
|
126
|
Chris@16
|
127 //helpers for move assignments
|
Chris@101
|
128 explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const value_compare &c)
|
Chris@16
|
129 : members_(boost::move(x.node_alloc()), c)
|
Chris@16
|
130 { this->icont().swap(x.icont()); }
|
Chris@16
|
131
|
Chris@16
|
132 void copy_assign_alloc(const node_alloc_holder &x)
|
Chris@101
|
133 {
|
Chris@16
|
134 container_detail::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag;
|
Chris@16
|
135 container_detail::assign_alloc( static_cast<NodeAlloc &>(this->members_)
|
Chris@16
|
136 , static_cast<const NodeAlloc &>(x.members_), flag);
|
Chris@16
|
137 }
|
Chris@16
|
138
|
Chris@16
|
139 void move_assign_alloc( node_alloc_holder &x)
|
Chris@16
|
140 {
|
Chris@16
|
141 container_detail::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
|
Chris@16
|
142 container_detail::move_alloc( static_cast<NodeAlloc &>(this->members_)
|
Chris@16
|
143 , static_cast<NodeAlloc &>(x.members_), flag);
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 ~node_alloc_holder()
|
Chris@16
|
147 { this->clear(alloc_version()); }
|
Chris@16
|
148
|
Chris@16
|
149 size_type max_size() const
|
Chris@16
|
150 { return allocator_traits_type::max_size(this->node_alloc()); }
|
Chris@16
|
151
|
Chris@16
|
152 NodePtr allocate_one()
|
Chris@16
|
153 { return AllocVersionTraits::allocate_one(this->node_alloc()); }
|
Chris@16
|
154
|
Chris@16
|
155 void deallocate_one(const NodePtr &p)
|
Chris@16
|
156 { AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
|
Chris@16
|
157
|
Chris@101
|
158 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
159
|
Chris@16
|
160 template<class ...Args>
|
Chris@16
|
161 NodePtr create_node(Args &&...args)
|
Chris@16
|
162 {
|
Chris@16
|
163 NodePtr p = this->allocate_one();
|
Chris@16
|
164 Deallocator node_deallocator(p, this->node_alloc());
|
Chris@16
|
165 allocator_traits<NodeAlloc>::construct
|
Chris@16
|
166 ( this->node_alloc()
|
Chris@16
|
167 , container_detail::addressof(p->m_data), boost::forward<Args>(args)...);
|
Chris@16
|
168 node_deallocator.release();
|
Chris@16
|
169 //This does not throw
|
Chris@16
|
170 typedef typename Node::hook_type hook_type;
|
Chris@101
|
171 ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
Chris@16
|
172 return (p);
|
Chris@16
|
173 }
|
Chris@16
|
174
|
Chris@101
|
175 #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
176 NodePtr create_node()
|
Chris@101
|
177 {
|
Chris@101
|
178 NodePtr p = this->allocate_one();
|
Chris@101
|
179 Deallocator node_deallocator(p, this->node_alloc());
|
Chris@101
|
180 allocator_traits<NodeAlloc>::construct
|
Chris@101
|
181 (this->node_alloc(), container_detail::addressof(p->m_data));
|
Chris@101
|
182 node_deallocator.release();
|
Chris@101
|
183 typedef typename Node::hook_type hook_type;
|
Chris@101
|
184 ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
Chris@101
|
185 return (p);
|
Chris@101
|
186 }
|
Chris@16
|
187
|
Chris@101
|
188 template<BOOST_MOVE_CLASS1>
|
Chris@101
|
189 NodePtr create_node(BOOST_MOVE_UREF1)
|
Chris@101
|
190 {
|
Chris@101
|
191 NodePtr p = this->allocate_one();
|
Chris@101
|
192 Deallocator node_deallocator(p, this->node_alloc());
|
Chris@101
|
193 allocator_traits<NodeAlloc>::construct
|
Chris@101
|
194 (this->node_alloc(), container_detail::addressof(p->m_data)
|
Chris@101
|
195 , BOOST_MOVE_FWD1);
|
Chris@101
|
196 node_deallocator.release();
|
Chris@101
|
197 typedef typename Node::hook_type hook_type;
|
Chris@101
|
198 ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
Chris@101
|
199 return (p);
|
Chris@101
|
200 }
|
Chris@16
|
201
|
Chris@101
|
202 template<BOOST_MOVE_CLASS2>
|
Chris@101
|
203 NodePtr create_node(BOOST_MOVE_UREF2)
|
Chris@101
|
204 {
|
Chris@101
|
205 NodePtr p = this->allocate_one();
|
Chris@101
|
206 Deallocator node_deallocator(p, this->node_alloc());
|
Chris@101
|
207 allocator_traits<NodeAlloc>::construct
|
Chris@101
|
208 (this->node_alloc(), container_detail::addressof(p->m_data)
|
Chris@101
|
209 , BOOST_MOVE_FWD2);
|
Chris@101
|
210 node_deallocator.release();
|
Chris@101
|
211 typedef typename Node::hook_type hook_type;
|
Chris@101
|
212 ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
Chris@101
|
213 return (p);
|
Chris@101
|
214 }
|
Chris@101
|
215
|
Chris@101
|
216 template<BOOST_MOVE_CLASS3>
|
Chris@101
|
217 NodePtr create_node(BOOST_MOVE_UREF3)
|
Chris@101
|
218 {
|
Chris@101
|
219 NodePtr p = this->allocate_one();
|
Chris@101
|
220 Deallocator node_deallocator(p, this->node_alloc());
|
Chris@101
|
221 allocator_traits<NodeAlloc>::construct
|
Chris@101
|
222 (this->node_alloc(), container_detail::addressof(p->m_data)
|
Chris@101
|
223 , BOOST_MOVE_FWD3);
|
Chris@101
|
224 node_deallocator.release();
|
Chris@101
|
225 typedef typename Node::hook_type hook_type;
|
Chris@101
|
226 ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
Chris@101
|
227 return (p);
|
Chris@101
|
228 }
|
Chris@101
|
229
|
Chris@101
|
230 template<BOOST_MOVE_CLASS4>
|
Chris@101
|
231 NodePtr create_node(BOOST_MOVE_UREF4)
|
Chris@101
|
232 {
|
Chris@101
|
233 NodePtr p = this->allocate_one();
|
Chris@101
|
234 Deallocator node_deallocator(p, this->node_alloc());
|
Chris@101
|
235 allocator_traits<NodeAlloc>::construct
|
Chris@101
|
236 (this->node_alloc(), container_detail::addressof(p->m_data)
|
Chris@101
|
237 , BOOST_MOVE_FWD4);
|
Chris@101
|
238 node_deallocator.release();
|
Chris@101
|
239 typedef typename Node::hook_type hook_type;
|
Chris@101
|
240 ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
Chris@101
|
241 return (p);
|
Chris@101
|
242 }
|
Chris@101
|
243
|
Chris@101
|
244 template<BOOST_MOVE_CLASS5>
|
Chris@101
|
245 NodePtr create_node(BOOST_MOVE_UREF5)
|
Chris@101
|
246 {
|
Chris@101
|
247 NodePtr p = this->allocate_one();
|
Chris@101
|
248 Deallocator node_deallocator(p, this->node_alloc());
|
Chris@101
|
249 allocator_traits<NodeAlloc>::construct
|
Chris@101
|
250 (this->node_alloc(), container_detail::addressof(p->m_data)
|
Chris@101
|
251 , BOOST_MOVE_FWD5);
|
Chris@101
|
252 node_deallocator.release();
|
Chris@101
|
253 typedef typename Node::hook_type hook_type;
|
Chris@101
|
254 ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
Chris@101
|
255 return (p);
|
Chris@101
|
256 }
|
Chris@101
|
257
|
Chris@101
|
258 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
259
|
Chris@16
|
260 template<class It>
|
Chris@16
|
261 NodePtr create_node_from_it(const It &it)
|
Chris@16
|
262 {
|
Chris@16
|
263 NodePtr p = this->allocate_one();
|
Chris@16
|
264 Deallocator node_deallocator(p, this->node_alloc());
|
Chris@16
|
265 ::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
|
Chris@16
|
266 node_deallocator.release();
|
Chris@16
|
267 //This does not throw
|
Chris@16
|
268 typedef typename Node::hook_type hook_type;
|
Chris@101
|
269 ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
Chris@16
|
270 return (p);
|
Chris@16
|
271 }
|
Chris@16
|
272
|
Chris@16
|
273 void destroy_node(const NodePtr &nodep)
|
Chris@16
|
274 {
|
Chris@16
|
275 allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
|
Chris@16
|
276 this->deallocate_one(nodep);
|
Chris@16
|
277 }
|
Chris@16
|
278
|
Chris@16
|
279 void swap(node_alloc_holder &x)
|
Chris@16
|
280 {
|
Chris@16
|
281 this->icont().swap(x.icont());
|
Chris@16
|
282 container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
|
Chris@16
|
283 container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
|
Chris@16
|
284 }
|
Chris@16
|
285
|
Chris@16
|
286 template<class FwdIterator, class Inserter>
|
Chris@16
|
287 void allocate_many_and_construct
|
Chris@16
|
288 (FwdIterator beg, difference_type n, Inserter inserter)
|
Chris@16
|
289 {
|
Chris@16
|
290 if(n){
|
Chris@16
|
291 typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain;
|
Chris@16
|
292
|
Chris@16
|
293 //Try to allocate memory in a single block
|
Chris@16
|
294 typedef typename multiallocation_chain::iterator multialloc_iterator;
|
Chris@16
|
295 multiallocation_chain mem;
|
Chris@16
|
296 NodeAlloc &nalloc = this->node_alloc();
|
Chris@16
|
297 node_allocator_version_traits_type::allocate_individual(nalloc, n, mem);
|
Chris@16
|
298 multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
|
Chris@16
|
299 mem.clear();
|
Chris@16
|
300 Node *p = 0;
|
Chris@16
|
301 BOOST_TRY{
|
Chris@16
|
302 Deallocator node_deallocator(NodePtr(), nalloc);
|
Chris@16
|
303 container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
|
Chris@16
|
304 while(n--){
|
Chris@101
|
305 p = container_detail::iterator_to_raw_pointer(itbeg);
|
Chris@16
|
306 node_deallocator.set(p);
|
Chris@16
|
307 ++itbeg;
|
Chris@16
|
308 //This can throw
|
Chris@16
|
309 boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
|
Chris@16
|
310 sdestructor.set(p);
|
Chris@16
|
311 ++beg;
|
Chris@16
|
312 //This does not throw
|
Chris@16
|
313 typedef typename Node::hook_type hook_type;
|
Chris@101
|
314 ::new(static_cast<hook_type*>(p), boost_container_new_t()) hook_type;
|
Chris@16
|
315 //This can throw in some containers (predicate might throw).
|
Chris@16
|
316 //(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
|
Chris@16
|
317 inserter(*p);
|
Chris@16
|
318 sdestructor.set(0);
|
Chris@16
|
319 }
|
Chris@16
|
320 sdestructor.release();
|
Chris@16
|
321 node_deallocator.release();
|
Chris@16
|
322 }
|
Chris@16
|
323 BOOST_CATCH(...){
|
Chris@16
|
324 mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
|
Chris@16
|
325 node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem);
|
Chris@16
|
326 BOOST_RETHROW
|
Chris@16
|
327 }
|
Chris@16
|
328 BOOST_CATCH_END
|
Chris@16
|
329 }
|
Chris@16
|
330 }
|
Chris@16
|
331
|
Chris@101
|
332 void clear(version_1)
|
Chris@16
|
333 { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
|
Chris@16
|
334
|
Chris@101
|
335 void clear(version_2)
|
Chris@16
|
336 {
|
Chris@16
|
337 typename NodeAlloc::multiallocation_chain chain;
|
Chris@16
|
338 allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
|
Chris@16
|
339 this->icont().clear_and_dispose(builder);
|
Chris@16
|
340 //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true));
|
Chris@16
|
341 if(!chain.empty())
|
Chris@16
|
342 this->node_alloc().deallocate_individual(chain);
|
Chris@16
|
343 }
|
Chris@16
|
344
|
Chris@101
|
345 icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1)
|
Chris@16
|
346 { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
|
Chris@16
|
347
|
Chris@101
|
348 icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2)
|
Chris@16
|
349 {
|
Chris@16
|
350 typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
|
Chris@16
|
351 NodeAlloc & nalloc = this->node_alloc();
|
Chris@16
|
352 multiallocation_chain chain;
|
Chris@16
|
353 allocator_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain);
|
Chris@16
|
354 icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder);
|
Chris@16
|
355 nalloc.deallocate_individual(chain);
|
Chris@16
|
356 return ret_it;
|
Chris@16
|
357 }
|
Chris@16
|
358
|
Chris@16
|
359 template<class Key, class Comparator>
|
Chris@101
|
360 size_type erase_key(const Key& k, const Comparator &comp, version_1)
|
Chris@16
|
361 { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
|
Chris@16
|
362
|
Chris@16
|
363 template<class Key, class Comparator>
|
Chris@101
|
364 size_type erase_key(const Key& k, const Comparator &comp, version_2)
|
Chris@16
|
365 {
|
Chris@16
|
366 allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
|
Chris@16
|
367 return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
|
Chris@16
|
368 }
|
Chris@16
|
369
|
Chris@16
|
370 protected:
|
Chris@16
|
371 struct cloner
|
Chris@16
|
372 {
|
Chris@101
|
373 explicit cloner(node_alloc_holder &holder)
|
Chris@16
|
374 : m_holder(holder)
|
Chris@16
|
375 {}
|
Chris@16
|
376
|
Chris@16
|
377 NodePtr operator()(const Node &other) const
|
Chris@16
|
378 { return m_holder.create_node(other.get_data()); }
|
Chris@16
|
379
|
Chris@16
|
380 node_alloc_holder &m_holder;
|
Chris@16
|
381 };
|
Chris@16
|
382
|
Chris@101
|
383 struct move_cloner
|
Chris@101
|
384 {
|
Chris@101
|
385 move_cloner(node_alloc_holder &holder)
|
Chris@101
|
386 : m_holder(holder)
|
Chris@101
|
387 {}
|
Chris@101
|
388
|
Chris@101
|
389 NodePtr operator()(Node &other)
|
Chris@101
|
390 { return m_holder.create_node(::boost::move(other.get_data())); }
|
Chris@101
|
391
|
Chris@101
|
392 node_alloc_holder &m_holder;
|
Chris@101
|
393 };
|
Chris@101
|
394
|
Chris@16
|
395 struct members_holder
|
Chris@16
|
396 : public NodeAlloc
|
Chris@16
|
397 {
|
Chris@16
|
398 private:
|
Chris@16
|
399 members_holder(const members_holder&);
|
Chris@16
|
400 members_holder & operator=(const members_holder&);
|
Chris@16
|
401
|
Chris@16
|
402 public:
|
Chris@16
|
403 members_holder()
|
Chris@16
|
404 : NodeAlloc(), m_icont()
|
Chris@16
|
405 {}
|
Chris@16
|
406
|
Chris@16
|
407 template<class ConvertibleToAlloc>
|
Chris@16
|
408 explicit members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc)
|
Chris@16
|
409 : NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
|
Chris@16
|
410 , m_icont()
|
Chris@16
|
411 {}
|
Chris@16
|
412
|
Chris@16
|
413 template<class ConvertibleToAlloc>
|
Chris@101
|
414 members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c)
|
Chris@16
|
415 : NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
|
Chris@16
|
416 , m_icont(typename ICont::value_compare(c))
|
Chris@16
|
417 {}
|
Chris@16
|
418
|
Chris@101
|
419 explicit members_holder(const value_compare &c)
|
Chris@16
|
420 : NodeAlloc()
|
Chris@16
|
421 , m_icont(typename ICont::value_compare(c))
|
Chris@16
|
422 {}
|
Chris@16
|
423
|
Chris@16
|
424 //The intrusive container
|
Chris@16
|
425 ICont m_icont;
|
Chris@16
|
426 };
|
Chris@16
|
427
|
Chris@16
|
428 ICont &non_const_icont() const
|
Chris@16
|
429 { return const_cast<ICont&>(this->members_.m_icont); }
|
Chris@16
|
430
|
Chris@16
|
431 ICont &icont()
|
Chris@16
|
432 { return this->members_.m_icont; }
|
Chris@16
|
433
|
Chris@16
|
434 const ICont &icont() const
|
Chris@16
|
435 { return this->members_.m_icont; }
|
Chris@16
|
436
|
Chris@16
|
437 NodeAlloc &node_alloc()
|
Chris@16
|
438 { return static_cast<NodeAlloc &>(this->members_); }
|
Chris@16
|
439
|
Chris@16
|
440 const NodeAlloc &node_alloc() const
|
Chris@16
|
441 { return static_cast<const NodeAlloc &>(this->members_); }
|
Chris@16
|
442
|
Chris@16
|
443 members_holder members_;
|
Chris@16
|
444 };
|
Chris@16
|
445
|
Chris@16
|
446 } //namespace container_detail {
|
Chris@16
|
447 } //namespace container {
|
Chris@16
|
448 } //namespace boost {
|
Chris@16
|
449
|
Chris@16
|
450 #include <boost/container/detail/config_end.hpp>
|
Chris@16
|
451
|
Chris@16
|
452 #endif // BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|