From fe2ac80bae3a096be981847dd80f93a02331677b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 25 Nov 2025 15:57:33 +0100 Subject: [PATCH] Backport uses allocator logic for older compilers. --- .../interprocess/allocators/adaptive_pool.hpp | 19 ++++++++++++++++++- .../interprocess/allocators/allocator.hpp | 17 +++++++++++++++++ .../allocators/cached_adaptive_pool.hpp | 2 +- .../allocators/cached_node_allocator.hpp | 2 +- .../allocators/detail/allocator_common.hpp | 17 +++++++++++++++++ .../allocators/node_allocator.hpp | 19 ++++++++++++++++++- .../allocators/private_adaptive_pool.hpp | 19 ++++++++++++++++++- .../allocators/private_node_allocator.hpp | 19 ++++++++++++++++++- 8 files changed, 108 insertions(+), 6 deletions(-) diff --git a/include/boost/interprocess/allocators/adaptive_pool.hpp b/include/boost/interprocess/allocators/adaptive_pool.hpp index 1342a19..9bdc7d2 100644 --- a/include/boost/interprocess/allocators/adaptive_pool.hpp +++ b/include/boost/interprocess/allocators/adaptive_pool.hpp @@ -173,6 +173,7 @@ class adaptive_pool_base segment_manager* get_segment_manager()const { return node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->get_segment_manager(); } + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Requires: Uses-allocator construction of T with allocator //! `segment_manager*` and constructor arguments `std::forward(args)...` //! is well-formed. [Note: uses-allocator construction is always well formed for @@ -191,6 +192,22 @@ class adaptive_pool_base (atd, this->get_segment_manager(), p, ::boost::forward(args)...); } + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + #define BOOST_CONTAINER_ALLOCATORS_ADAPTIVE_POOL_CONSTRUCT_CODE(N) \ + template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + boost::container::dtl::allocator_traits_dummy atd;\ + boost::container::dtl::dispatch_uses_allocator\ + (atd, this->get_segment_manager(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATORS_ADAPTIVE_POOL_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_ALLOCATORS_ADAPTIVE_POOL_CONSTRUCT_CODE + + #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //!Swaps allocators. Does not throw. If each allocator is placed in a //!different memory segment, the result is undefined. friend void swap(self_t &alloc1, self_t &alloc2) @@ -413,7 +430,7 @@ class adaptive_pool //! //! Throws: Nothing unless the constructor for T throws. template - void construct(U* p, BOOST_FWD_REF(Args)...args); + void construct(U* p, Args&& ...args); //!Returns maximum the number of objects the previously allocated memory //!pointed by p can hold. This size only works for memory allocated with diff --git a/include/boost/interprocess/allocators/allocator.hpp b/include/boost/interprocess/allocators/allocator.hpp index 0214e3a..14c85cc 100644 --- a/include/boost/interprocess/allocators/allocator.hpp +++ b/include/boost/interprocess/allocators/allocator.hpp @@ -160,6 +160,7 @@ class allocator void deallocate(const pointer &ptr, size_type) { mp_mngr->deallocate((void*)ipcdetail::to_raw_pointer(ptr)); } + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Requires: Uses-allocator construction of T with allocator //! `segment_manager*` and constructor arguments `std::forward(args)...` //! is well-formed. [Note: uses-allocator construction is always well formed for @@ -178,6 +179,22 @@ class allocator (atd, this->get_segment_manager(), p, ::boost::forward(args)...); } + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + #define BOOST_CONTAINER_ALLOCATORS_ALLOCATOR_CONSTRUCT_CODE(N) \ + template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + boost::container::dtl::allocator_traits_dummy atd;\ + boost::container::dtl::dispatch_uses_allocator\ + (atd, this->get_segment_manager(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATORS_ALLOCATOR_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_ALLOCATORS_ALLOCATOR_CONSTRUCT_CODE + + #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //!Returns the number of elements that could be allocated. //!Never throws size_type max_size() const diff --git a/include/boost/interprocess/allocators/cached_adaptive_pool.hpp b/include/boost/interprocess/allocators/cached_adaptive_pool.hpp index d013b33..8579911 100644 --- a/include/boost/interprocess/allocators/cached_adaptive_pool.hpp +++ b/include/boost/interprocess/allocators/cached_adaptive_pool.hpp @@ -292,7 +292,7 @@ class cached_adaptive_pool //! //! Throws: Nothing unless the constructor for T throws. template - void construct(U* p, BOOST_FWD_REF(Args)...args); + void construct(U* p, Args&& ...args); //!Returns maximum the number of objects the previously allocated memory //!pointed by p can hold. This size only works for memory allocated with diff --git a/include/boost/interprocess/allocators/cached_node_allocator.hpp b/include/boost/interprocess/allocators/cached_node_allocator.hpp index 916033a..f00902d 100644 --- a/include/boost/interprocess/allocators/cached_node_allocator.hpp +++ b/include/boost/interprocess/allocators/cached_node_allocator.hpp @@ -264,7 +264,7 @@ class cached_node_allocator //! //! Throws: Nothing unless the constructor for T throws. template - void construct(U* p, BOOST_FWD_REF(Args)...args); + void construct(U* p, Args&& ...args); //!Destroys object. Throws if object's //!destructor throws diff --git a/include/boost/interprocess/allocators/detail/allocator_common.hpp b/include/boost/interprocess/allocators/detail/allocator_common.hpp index ce419e4..84f9eec 100644 --- a/include/boost/interprocess/allocators/detail/allocator_common.hpp +++ b/include/boost/interprocess/allocators/detail/allocator_common.hpp @@ -620,6 +620,7 @@ class cached_allocator_impl segment_manager* get_segment_manager()const { return m_cache.get_segment_manager(); } + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Requires: Uses-allocator construction of T with allocator //! `segment_manager*` and constructor arguments `std::forward(args)...` //! is well-formed. [Note: uses-allocator construction is always well formed for @@ -638,6 +639,22 @@ class cached_allocator_impl (atd, this->get_segment_manager(), p, ::boost::forward(args)...); } + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + #define BOOST_CONTAINER_ALLOCATORS_ALLOCATOR_COMMON_CONSTRUCT_CODE(N) \ + template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + boost::container::dtl::allocator_traits_dummy atd;\ + boost::container::dtl::dispatch_uses_allocator\ + (atd, this->get_segment_manager(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATORS_ALLOCATOR_COMMON_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_ALLOCATORS_ALLOCATOR_COMMON_CONSTRUCT_CODE + + #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //!Sets the new max cached nodes value. This can provoke deallocations //!if "newmax" is less than current cached nodes. Never throws void set_max_cached_nodes(size_type newmax) diff --git a/include/boost/interprocess/allocators/node_allocator.hpp b/include/boost/interprocess/allocators/node_allocator.hpp index d2133ad..c808bb6 100644 --- a/include/boost/interprocess/allocators/node_allocator.hpp +++ b/include/boost/interprocess/allocators/node_allocator.hpp @@ -172,6 +172,7 @@ class node_allocator_base segment_manager* get_segment_manager()const { return node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->get_segment_manager(); } + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Requires: Uses-allocator construction of T with allocator //! `segment_manager*` and constructor arguments `std::forward(args)...` //! is well-formed. [Note: uses-allocator construction is always well formed for @@ -190,6 +191,22 @@ class node_allocator_base (atd, this->get_segment_manager(), p, ::boost::forward(args)...); } + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + #define BOOST_CONTAINER_ALLOCATORS_NODE_ALLOCATOR_CONSTRUCT_CODE(N) \ + template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + boost::container::dtl::allocator_traits_dummy atd;\ + boost::container::dtl::dispatch_uses_allocator\ + (atd, this->get_segment_manager(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATORS_NODE_ALLOCATOR_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_ALLOCATORS_NODE_ALLOCATOR_CONSTRUCT_CODE + + #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //!Swaps allocators. Does not throw. If each allocator is placed in a //!different memory segment, the result is undefined. friend void swap(self_t &alloc1, self_t &alloc2) @@ -398,7 +415,7 @@ class node_allocator //! //! Throws: Nothing unless the constructor for T throws. template - void construct(U* p, BOOST_FWD_REF(Args)...args); + void construct(U* p, Args&& ...args); //!Returns maximum the number of objects the previously allocated memory //!pointed by p can hold. This size only works for memory allocated with diff --git a/include/boost/interprocess/allocators/private_adaptive_pool.hpp b/include/boost/interprocess/allocators/private_adaptive_pool.hpp index f334edc..b052725 100644 --- a/include/boost/interprocess/allocators/private_adaptive_pool.hpp +++ b/include/boost/interprocess/allocators/private_adaptive_pool.hpp @@ -177,6 +177,7 @@ class private_adaptive_pool_base segment_manager* get_segment_manager()const { return m_node_pool.get_segment_manager(); } + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Requires: Uses-allocator construction of T with allocator //! `segment_manager*` and constructor arguments `std::forward(args)...` //! is well-formed. [Note: uses-allocator construction is always well formed for @@ -195,6 +196,22 @@ class private_adaptive_pool_base (atd, this->get_segment_manager(), p, ::boost::forward(args)...); } + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + #define BOOST_CONTAINER_ALLOCATORS_PRIVATE_ADAPTIVE_POOL_CONSTRUCT_CODE(N) \ + template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + boost::container::dtl::allocator_traits_dummy atd;\ + boost::container::dtl::dispatch_uses_allocator\ + (atd, this->get_segment_manager(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATORS_PRIVATE_ADAPTIVE_POOL_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_ALLOCATORS_PRIVATE_ADAPTIVE_POOL_CONSTRUCT_CODE + + #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //!Returns the internal node pool. Never throws node_pool_t* get_node_pool() const { return const_cast(&m_node_pool); } @@ -443,7 +460,7 @@ class private_adaptive_pool //! //! Throws: Nothing unless the constructor for T throws. template - void construct(U* p, BOOST_FWD_REF(Args)...args); + void construct(U* p, Args&& ...args); //!Returns maximum the number of objects the previously allocated memory //!pointed by p can hold. This size only works for memory allocated with diff --git a/include/boost/interprocess/allocators/private_node_allocator.hpp b/include/boost/interprocess/allocators/private_node_allocator.hpp index f45e892..b760281 100644 --- a/include/boost/interprocess/allocators/private_node_allocator.hpp +++ b/include/boost/interprocess/allocators/private_node_allocator.hpp @@ -167,6 +167,7 @@ class private_node_allocator_base segment_manager* get_segment_manager()const { return m_node_pool.get_segment_manager(); } + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Requires: Uses-allocator construction of T with allocator //! `segment_manager*` and constructor arguments `std::forward(args)...` //! is well-formed. [Note: uses-allocator construction is always well formed for @@ -185,6 +186,22 @@ class private_node_allocator_base (atd, this->get_segment_manager(), p, ::boost::forward(args)...); } + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + #define BOOST_CONTAINER_ALLOCATORS_PRIVATE_NODE_ALLOCATOR_CONSTRUCT_CODE(N) \ + template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + boost::container::dtl::allocator_traits_dummy atd;\ + boost::container::dtl::dispatch_uses_allocator\ + (atd, this->get_segment_manager(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATORS_PRIVATE_NODE_ALLOCATOR_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_ALLOCATORS_PRIVATE_NODE_ALLOCATOR_CONSTRUCT_CODE + + #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //!Returns the internal node pool. Never throws node_pool_t* get_node_pool() const { return const_cast(&m_node_pool); } @@ -418,7 +435,7 @@ class private_node_allocator //! //! Throws: Nothing unless the constructor for T throws. template - void construct(U* p, BOOST_FWD_REF(Args)...args); + void construct(U* p, Args&& ...args); //!Returns maximum the number of objects the previously allocated memory //!pointed by p can hold. This size only works for memory allocated with