From 8c9080f11f15d509439f7cc1d9ee69b15f5bf5c7 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 18 Apr 2017 10:14:26 +0100 Subject: [PATCH] Document changes to allocator use --- doc/compliance.qbk | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/doc/compliance.qbk b/doc/compliance.qbk index 771e473d..b0fd9472 100644 --- a/doc/compliance.qbk +++ b/doc/compliance.qbk @@ -51,23 +51,32 @@ Due to imperfect move emulation, some assignments might check `propagate_on_container_copy_assignment` on some compilers and `propagate_on_container_move_assignment` on others. -The use of the allocator's construct and destruct methods might be a bit -surprising. -Nodes are constructed and destructed using the allocator, but the elements -are stored in aligned space within the node and constructed and destructed -by calling the constructor and destructor directly. +[endsect] -In C++11 the allocator's construct function has the signature: +[section:construction Construction/Destruction using allocators] - template - void construct(U* p, Args&&... args); +The following support is required for full use of C++11 style +construction/destruction: -which supports calling `construct` for the contained object, but -most existing allocators don't support this. If member function detection -was good enough then with old allocators it would fall back to calling -the element's constructor directly but in general, detection isn't good -enough to do this which is why Boost.Unordered just calls the constructor -directly every time. In most cases this will work okay. + * Variadic templates. + * Piecewise construction of `std::pair`. + * Either `std::allocator_traits` or expression SFINAE. + +This is detected using Boost.Config. The macro +`BOOST_UNORDERED_CXX11_CONSTRUCTION` will be set to 1 if it is found, or 0 +otherwise. + +When this is the case `allocator_traits::construct` and +`allocator_traits::destroy` will always be used, apart from when piecewise +constructing a `std::pair` using `boost::tuple` (see [link +unordered.compliance.pairs below]), but that should be easily avoided. + +When support is not available `allocator_traits::construct` and +`allocator_traits::destroy` are never called. + +[endsect] + +[section:pointer_traits Pointer Traits] `pointer_traits` aren't used. Instead, pointer types are obtained from rebound allocators, this can cause problems if the allocator can't be @@ -77,6 +86,7 @@ is used to obtain a const pointer. [endsect] +[#unordered.compliance.pairs] [section:pairs Pairs] Since the containers use `std::pair` they're limited to the version