Skip to content

Commit 3a9f2c2

Browse files
committed
Implement "uses allocator" for all allocator.
1 parent 55017f4 commit 3a9f2c2

8 files changed

Lines changed: 229 additions & 67 deletions

File tree

include/boost/interprocess/allocators/adaptive_pool.hpp

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,24 @@
2222
#include <boost/interprocess/detail/config_begin.hpp>
2323
#include <boost/interprocess/detail/workaround.hpp>
2424

25-
#include <boost/intrusive/pointer_traits.hpp>
25+
#include <boost/assert.hpp>
2626

27+
#include <boost/intrusive/pointer_traits.hpp>
2728
#include <boost/interprocess/interprocess_fwd.hpp>
28-
#include <boost/assert.hpp>
29-
#include <boost/container/detail/addressof.hpp>
29+
30+
#include <boost/interprocess/containers/version_type.hpp>
31+
#include <boost/interprocess/exceptions.hpp>
32+
3033
#include <boost/interprocess/detail/utilities.hpp>
3134
#include <boost/interprocess/detail/type_traits.hpp>
35+
#include <boost/interprocess/detail/mpl.hpp>
3236
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
33-
#include <boost/interprocess/containers/version_type.hpp>
34-
#include <boost/interprocess/exceptions.hpp>
3537
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
38+
3639
#include <boost/container/detail/multiallocation_chain.hpp>
37-
#include <boost/interprocess/detail/mpl.hpp>
40+
#include <boost/container/detail/dispatch_uses_allocator.hpp>
41+
#include <boost/container/detail/addressof.hpp>
42+
3843
#include <boost/move/adl_move_swap.hpp>
3944
#include <cstddef>
4045

@@ -168,6 +173,24 @@ class adaptive_pool_base
168173
segment_manager* get_segment_manager()const
169174
{ return node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->get_segment_manager(); }
170175

176+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
177+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
178+
//! is well-formed. [Note: uses-allocator construction is always well formed for
179+
//! types that do not use allocators. - end note]
180+
//!
181+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
182+
//! argument constructible from `segment_manager*`
183+
//! and constructor arguments `std::forward<Args>(args)...`.
184+
//!
185+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
186+
template < typename U, class ...Args>
187+
inline void construct(U* p, BOOST_FWD_REF(Args)...args)
188+
{
189+
boost::container::dtl::allocator_traits_dummy<U> atd;
190+
boost::container::dtl::dispatch_uses_allocator
191+
(atd, this->get_segment_manager(), p, ::boost::forward<Args>(args)...);
192+
}
193+
171194
//!Swaps allocators. Does not throw. If each allocator is placed in a
172195
//!different memory segment, the result is undefined.
173196
friend void swap(self_t &alloc1, self_t &alloc2)
@@ -378,15 +401,20 @@ class adaptive_pool
378401
//!Returns address of non mutable object.
379402
//!Never throws
380403
const_pointer address(const_reference value) const;
381-
/*
382-
//!Copy construct an object.
383-
//!Throws if T's copy constructor throws
384-
void construct(const pointer &ptr, const_reference v);
385-
386-
//!Destroys object. Throws if object's
387-
//!destructor throws
388-
void destroy(const pointer &ptr);
389-
*/
404+
405+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
406+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
407+
//! is well-formed. [Note: uses-allocator construction is always well formed for
408+
//! types that do not use allocators. - end note]
409+
//!
410+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
411+
//! argument constructible from `segment_manager*`
412+
//! and constructor arguments `std::forward<Args>(args)...`.
413+
//!
414+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
415+
template <typename U, class ...Args>
416+
void construct(U* p, BOOST_FWD_REF(Args)...args);
417+
390418
//!Returns maximum the number of objects the previously allocated memory
391419
//!pointed by p can hold. This size only works for memory allocated with
392420
//!allocate, allocation_command and allocate_many.

include/boost/interprocess/allocators/allocator.hpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@
3232
#include <boost/interprocess/containers/version_type.hpp>
3333
#include <boost/interprocess/exceptions.hpp>
3434
#include <boost/assert.hpp>
35-
#include <boost/container/detail/addressof.hpp>
3635
#include <boost/interprocess/detail/type_traits.hpp>
36+
3737
#include <boost/container/detail/placement_new.hpp>
38+
#include <boost/container/detail/addressof.hpp>
39+
#include <boost/container/detail/dispatch_uses_allocator.hpp>
3840

3941
#include <cstddef>
4042
#include <stdexcept>
@@ -158,6 +160,24 @@ class allocator
158160
void deallocate(const pointer &ptr, size_type)
159161
{ mp_mngr->deallocate((void*)ipcdetail::to_raw_pointer(ptr)); }
160162

163+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
164+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
165+
//! is well-formed. [Note: uses-allocator construction is always well formed for
166+
//! types that do not use allocators. - end note]
167+
//!
168+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
169+
//! argument constructible from `segment_manager*`
170+
//! and constructor arguments `std::forward<Args>(args)...`.
171+
//!
172+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
173+
template < typename U, class ...Args>
174+
inline void construct(U* p, BOOST_FWD_REF(Args)...args)
175+
{
176+
boost::container::dtl::allocator_traits_dummy<U> atd;
177+
boost::container::dtl::dispatch_uses_allocator
178+
(atd, this->get_segment_manager(), p, ::boost::forward<Args>(args)...);
179+
}
180+
161181
//!Returns the number of elements that could be allocated.
162182
//!Never throws
163183
size_type max_size() const

include/boost/interprocess/allocators/cached_adaptive_pool.hpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -281,13 +281,18 @@ class cached_adaptive_pool
281281
//!Never throws
282282
const_pointer address(const_reference value) const;
283283

284-
//!Copy construct an object.
285-
//!Throws if T's copy constructor throws
286-
void construct(const pointer &ptr, const_reference v);
287-
288-
//!Destroys object. Throws if object's
289-
//!destructor throws
290-
void destroy(const pointer &ptr);
284+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
285+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
286+
//! is well-formed. [Note: uses-allocator construction is always well formed for
287+
//! types that do not use allocators. - end note]
288+
//!
289+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
290+
//! argument constructible from `segment_manager*`
291+
//! and constructor arguments `std::forward<Args>(args)...`.
292+
//!
293+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
294+
template <typename U, class ...Args>
295+
void construct(U* p, BOOST_FWD_REF(Args)...args);
291296

292297
//!Returns maximum the number of objects the previously allocated memory
293298
//!pointed by p can hold. This size only works for memory allocated with

include/boost/interprocess/allocators/cached_node_allocator.hpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@
2323
#include <boost/interprocess/detail/workaround.hpp>
2424

2525
#include <boost/interprocess/interprocess_fwd.hpp>
26+
2627
#include <boost/interprocess/allocators/detail/node_pool.hpp>
2728
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
28-
#include <boost/interprocess/detail/workaround.hpp>
29+
#include <boost/interprocess/allocators/detail/node_tools.hpp>
2930
#include <boost/interprocess/detail/utilities.hpp>
3031
#include <boost/interprocess/containers/version_type.hpp>
31-
#include <boost/interprocess/allocators/detail/node_tools.hpp>
32+
33+
#include <boost/container/detail/dispatch_uses_allocator.hpp>
34+
3235
#include <cstddef>
3336

3437
//!\file
@@ -250,13 +253,18 @@ class cached_node_allocator
250253
//!Never throws
251254
pointer address(reference value) const;
252255

253-
//!Returns address of non mutable object.
254-
//!Never throws
255-
const_pointer address(const_reference value) const;
256-
257-
//!Default construct an object.
258-
//!Throws if T's default constructor throws
259-
void construct(const pointer &ptr, const_reference v);
256+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
257+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
258+
//! is well-formed. [Note: uses-allocator construction is always well formed for
259+
//! types that do not use allocators. - end note]
260+
//!
261+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
262+
//! argument constructible from `segment_manager*`
263+
//! and constructor arguments `std::forward<Args>(args)...`.
264+
//!
265+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
266+
template <typename U, class ...Args>
267+
void construct(U* p, BOOST_FWD_REF(Args)...args);
260268

261269
//!Destroys object. Throws if object's
262270
//!destructor throws

include/boost/interprocess/allocators/detail/allocator_common.hpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,27 @@
2222
#include <boost/interprocess/detail/config_begin.hpp>
2323
#include <boost/interprocess/detail/workaround.hpp>
2424

25-
#include <boost/intrusive/pointer_traits.hpp>
25+
#include <boost/assert.hpp> //BOOST_ASSERT
2626

2727
#include <boost/interprocess/interprocess_fwd.hpp>
28-
#include <boost/interprocess/detail/utilities.hpp> //to_raw_pointer
29-
#include <boost/container/detail/addressof.hpp> //boost::container::dtl:addressof
30-
#include <boost/assert.hpp> //BOOST_ASSERT
28+
3129
#include <boost/interprocess/exceptions.hpp> //bad_alloc
3230
#include <boost/interprocess/sync/scoped_lock.hpp> //scoped_lock
3331
#include <boost/interprocess/containers/allocation_type.hpp> //boost::interprocess::allocation_type
34-
#include <boost/container/detail/multiallocation_chain.hpp>
3532
#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
33+
3634
#include <boost/interprocess/detail/segment_manager_helper.hpp>
37-
#include <boost/move/utility_core.hpp>
3835
#include <boost/interprocess/detail/type_traits.hpp>
39-
#include <boost/interprocess/detail/utilities.hpp>
36+
#include <boost/interprocess/detail/utilities.hpp> //to_raw_pointer
37+
38+
#include <boost/intrusive/pointer_traits.hpp>
39+
4040
#include <boost/container/detail/placement_new.hpp>
41+
#include <boost/container/detail/dispatch_uses_allocator.hpp>
42+
#include <boost/container/detail/multiallocation_chain.hpp>
43+
#include <boost/container/detail/addressof.hpp> //boost::container::dtl:addressof
44+
45+
#include <boost/move/utility_core.hpp>
4146
#include <boost/move/adl_move_swap.hpp>
4247

4348
namespace boost {
@@ -615,6 +620,24 @@ class cached_allocator_impl
615620
segment_manager* get_segment_manager()const
616621
{ return m_cache.get_segment_manager(); }
617622

623+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
624+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
625+
//! is well-formed. [Note: uses-allocator construction is always well formed for
626+
//! types that do not use allocators. - end note]
627+
//!
628+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
629+
//! argument constructible from `segment_manager*`
630+
//! and constructor arguments `std::forward<Args>(args)...`.
631+
//!
632+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
633+
template < typename U, class ...Args>
634+
inline void construct(U* p, BOOST_FWD_REF(Args)...args)
635+
{
636+
boost::container::dtl::allocator_traits_dummy<U> atd;
637+
boost::container::dtl::dispatch_uses_allocator
638+
(atd, this->get_segment_manager(), p, ::boost::forward<Args>(args)...);
639+
}
640+
618641
//!Sets the new max cached nodes value. This can provoke deallocations
619642
//!if "newmax" is less than current cached nodes. Never throws
620643
void set_max_cached_nodes(size_type newmax)

include/boost/interprocess/allocators/node_allocator.hpp

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,23 @@
2222
#include <boost/interprocess/detail/config_begin.hpp>
2323
#include <boost/interprocess/detail/workaround.hpp>
2424

25+
#include <boost/assert.hpp>
26+
2527
#include <boost/intrusive/pointer_traits.hpp>
2628

2729
#include <boost/interprocess/interprocess_fwd.hpp>
28-
#include <boost/assert.hpp>
29-
#include <boost/container/detail/addressof.hpp>
30-
#include <boost/interprocess/detail/utilities.hpp>
31-
#include <boost/interprocess/detail/type_traits.hpp>
3230
#include <boost/interprocess/allocators/detail/node_pool.hpp>
3331
#include <boost/interprocess/containers/version_type.hpp>
34-
#include <boost/container/detail/multiallocation_chain.hpp>
3532
#include <boost/interprocess/exceptions.hpp>
3633
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
34+
#include <boost/interprocess/detail/utilities.hpp>
35+
#include <boost/interprocess/detail/type_traits.hpp>
36+
37+
38+
#include <boost/container/detail/dispatch_uses_allocator.hpp>
39+
#include <boost/container/detail/multiallocation_chain.hpp>
40+
#include <boost/container/detail/addressof.hpp>
41+
3742
#include <boost/move/adl_move_swap.hpp>
3843
#include <cstddef>
3944

@@ -167,6 +172,24 @@ class node_allocator_base
167172
segment_manager* get_segment_manager()const
168173
{ return node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->get_segment_manager(); }
169174

175+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
176+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
177+
//! is well-formed. [Note: uses-allocator construction is always well formed for
178+
//! types that do not use allocators. - end note]
179+
//!
180+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
181+
//! argument constructible from `segment_manager*`
182+
//! and constructor arguments `std::forward<Args>(args)...`.
183+
//!
184+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
185+
template < typename U, class ...Args>
186+
inline void construct(U* p, BOOST_FWD_REF(Args)...args)
187+
{
188+
boost::container::dtl::allocator_traits_dummy<U> atd;
189+
boost::container::dtl::dispatch_uses_allocator
190+
(atd, this->get_segment_manager(), p, ::boost::forward<Args>(args)...);
191+
}
192+
170193
//!Swaps allocators. Does not throw. If each allocator is placed in a
171194
//!different memory segment, the result is undefined.
172195
friend void swap(self_t &alloc1, self_t &alloc2)
@@ -364,13 +387,18 @@ class node_allocator
364387
//!Never throws
365388
const_pointer address(const_reference value) const;
366389

367-
//!Copy construct an object.
368-
//!Throws if T's copy constructor throws
369-
void construct(const pointer &ptr, const_reference v);
370-
371-
//!Destroys object. Throws if object's
372-
//!destructor throws
373-
void destroy(const pointer &ptr);
390+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
391+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
392+
//! is well-formed. [Note: uses-allocator construction is always well formed for
393+
//! types that do not use allocators. - end note]
394+
//!
395+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
396+
//! argument constructible from `segment_manager*`
397+
//! and constructor arguments `std::forward<Args>(args)...`.
398+
//!
399+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
400+
template <typename U, class ...Args>
401+
void construct(U* p, BOOST_FWD_REF(Args)...args);
374402

375403
//!Returns maximum the number of objects the previously allocated memory
376404
//!pointed by p can hold. This size only works for memory allocated with

include/boost/interprocess/allocators/private_adaptive_pool.hpp

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
#include <boost/container/detail/multiallocation_chain.hpp>
3333
#include <boost/interprocess/exceptions.hpp>
3434
#include <boost/interprocess/detail/utilities.hpp>
35-
#include <boost/interprocess/detail/workaround.hpp>
35+
36+
#include <boost/container/detail/dispatch_uses_allocator.hpp>
37+
3638
#include <boost/move/adl_move_swap.hpp>
3739
#include <cstddef>
3840

@@ -175,6 +177,24 @@ class private_adaptive_pool_base
175177
segment_manager* get_segment_manager()const
176178
{ return m_node_pool.get_segment_manager(); }
177179

180+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
181+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
182+
//! is well-formed. [Note: uses-allocator construction is always well formed for
183+
//! types that do not use allocators. - end note]
184+
//!
185+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
186+
//! argument constructible from `segment_manager*`
187+
//! and constructor arguments `std::forward<Args>(args)...`.
188+
//!
189+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
190+
template < typename U, class ...Args>
191+
inline void construct(U* p, BOOST_FWD_REF(Args)...args)
192+
{
193+
boost::container::dtl::allocator_traits_dummy<U> atd;
194+
boost::container::dtl::dispatch_uses_allocator
195+
(atd, this->get_segment_manager(), p, ::boost::forward<Args>(args)...);
196+
}
197+
178198
//!Returns the internal node pool. Never throws
179199
node_pool_t* get_node_pool() const
180200
{ return const_cast<node_pool_t*>(&m_node_pool); }
@@ -412,13 +432,18 @@ class private_adaptive_pool
412432
//!Never throws
413433
const_pointer address(const_reference value) const;
414434

415-
//!Copy construct an object.
416-
//!Throws if T's copy constructor throws
417-
void construct(const pointer &ptr, const_reference v);
418-
419-
//!Destroys object. Throws if object's
420-
//!destructor throws
421-
void destroy(const pointer &ptr);
435+
//! <b>Requires</b>: Uses-allocator construction of T with allocator
436+
//! `segment_manager*` and constructor arguments `std::forward<Args>(args)...`
437+
//! is well-formed. [Note: uses-allocator construction is always well formed for
438+
//! types that do not use allocators. - end note]
439+
//!
440+
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
441+
//! argument constructible from `segment_manager*`
442+
//! and constructor arguments `std::forward<Args>(args)...`.
443+
//!
444+
//! <b>Throws</b>: Nothing unless the constructor for T throws.
445+
template <typename U, class ...Args>
446+
void construct(U* p, BOOST_FWD_REF(Args)...args);
422447

423448
//!Returns maximum the number of objects the previously allocated memory
424449
//!pointed by p can hold. This size only works for memory allocated with

0 commit comments

Comments
 (0)