std::scoped_allocator_adaptor
<scoped_allocator>
class scoped_allocator_adaptor
The std::scoped_allocator_adaptor
class template is an allocator which can be used with multilevel containers (vector of sets of lists of tuples of maps, etc). It is instantiated with one outer allocator type OuterAlloc
and zero or more inner allocator types InnerAlloc...
. A container constructed directly with a scoped_allocator_adaptor
uses OuterAlloc
to allocate its elements, but if an element is itself a container, it uses the first inner allocator. The elements of that container, if they are themselves containers, use the second inner allocator, etc. If there are more levels to the container than there are inner allocators, the last inner allocator is reused for all further nested containers.
The purpose of this adaptor is to correctly initialize stateful allocators in nested containers, such as when all levels of a nested container must be placed in the same shared memory segment. The adaptor's constructor takes the arguments for all allocators in the list, and each nested container obtains its allocator's state from the adaptor as needed.
For the purpose of scoped_allocator_adaptor
, if the next inner allocator is A
, any class T
for which std::uses_allocator <T,A>::value == true participates in the recursion as if it was a container. Additionally, std::pair is treated as such a container by specific overloads of scoped_allocator_adaptor::construct.
Typical implementation holds an instance of a std::scoped_allocator_adaptor<InnerAllocs...>
as a member object.
Note that std::pmr::polymorphic_allocators propagate to nested containers following uses-allocator construction and do not need (and do not work with) std::scoped_allocator_adaptor
.
Contents
[edit] Nested types
outer_allocator_type
OuterAlloc
inner_allocator_type
- scoped_allocator_adaptor<OuterAlloc> if sizeof...(InnerAllocs) is zero
- scoped_allocator_adaptor<InnerAllocs...> otherwise
value_type
std::allocator_traits <OuterAlloc>::value_type
size_type
std::allocator_traits <OuterAlloc>::size_type
difference_type
std::allocator_traits <OuterAlloc>::difference_type
pointer
std::allocator_traits <OuterAlloc>::pointer
const_pointer
std::allocator_traits <OuterAlloc>::const_pointer
void_pointer
std::allocator_traits <OuterAlloc>::void_pointer
const_void_pointer
std::allocator_traits <OuterAlloc>::const_void_pointer
Given the set of OuterAlloc
and InnerAlloc...
as Allocs
:
propagate_on_container_copy_assignment
- std::true_type if there exists a type
A
inAllocs
such that std::allocator_traits <A>::
propagate_on_container_copy_assignment::value is true - std::false_type otherwise
propagate_on_container_move_assignment
- std::true_type if there exists a type
A
inAllocs
such that std::allocator_traits <A>::
propagate_on_container_move_assignment::value is true - std::false_type otherwise
propagate_on_container_swap
- std::true_type if there exists a type
A
inAllocs
such that std::allocator_traits <A>::
propagate_on_container_swap::value is true - std::false_type otherwise
is_always_equal
- std::true_type if there exists a type
A
inAllocs
such that std::allocator_traits <A>::
is_always_equal::value is true - std::false_type otherwise
[edit] Member functions
(public member function) [edit]
(public member function) [edit]
Exposition-only function templates
(exposition-only member function*)
(exposition-only member function*)
[edit] Non-member functions
[edit] Deduction guides (since C++17)
[edit] Nested classes
rebind
template< class T >struct rebind
{
using other = scoped_allocator_adaptor
<std::allocator_traits <OuterAlloc>::template rebind_alloc<T>,
InnerAllocs...>;
};
[edit] Example
#include <boost/interprocess/allocators/adaptive_pool.hpp> #include <boost/interprocess/managed_shared_memory.hpp> #include <scoped_allocator> #include <vector> namespace bi = boost::interprocess; template<class T> using alloc = bi::adaptive_pool<T, bi::managed_shared_memory::segment_manager>; using ipc_row = std::vector <int, alloc<int>>; using ipc_matrix = std::vector <ipc_row, std::scoped_allocator_adaptor<alloc<ipc_row>>>; int main() { bi::managed_shared_memory s(bi::create_only, "Demo", 65536); // create vector of vectors in shared memory ipc_matrix v(s.get_segment_manager()); // for all these additions, the inner vectors obtain their allocator arguments // from the outer vector's scoped_allocator_adaptor v.resize(1); v[0].push_back(1); v.emplace_back(2); std::vector <int> local_row = {1, 2, 3}; v.emplace_back(local_row.begin(), local_row.end()); bi::shared_memory_object::remove("Demo"); }
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 2108 | C++11 | there was no way to show if scoped_allocator_adaptor is stateless
|
provided is_always_equal
|