Skip to main content

std::scoped_allocator_adaptor

Defined inscoped_allocator
Since C++11
template< class OuterAlloc, class... InnerAllocs >
class scoped_allocator_adaptor : public OuterAlloc;

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.

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.

Member types

pubTypeDefinition
pubouter_allocator_typeOuterAlloc
pubinner_allocator_typescoped_allocator_adaptor<InnerAllocs...> or, if sizeof...(InnerAllocs) == 0, scoped_allocator_adaptor<OuterAlloc>
pubvalue_type
std::allocator_traits<OuterAlloc>::value_type
pubsize_type
std::allocator_traits<OuterAlloc>::size_type
pubpointer
std::allocator_traits<OuterAlloc>::pointer
pubconst_pointer
std::allocator_traits<OuterAlloc>::const_pointer
pubconst_void_pointer
std::allocator_traits<OuterAlloc>::const_void_pointer
pubpropagate_on_container_copy_assignmentstd::true_type if std::allocator_traits<A>::propagate_on_container_copy_assignment::value is true for at least one allocator A among OuterAlloc and InnerAlloc...
pubpropagate_on_container_move_assignmentstd::true_type if std::allocator_traits<A>::propagate_on_container_move_assignment::value is true for at least one allocator A among OuterAlloc and InnerAlloc...
pubpropagate_on_container_swapstd::true_type if std::allocator_traits<A>::propagate_on_container_swap::value is true for at least one allocator A among OuterAlloc and InnerAlloc...
pubis_always_equalstd::true_type if std::allocator_traits<A>::propagate_on_container_swap::value is true for at least one allocator A among OuterAlloc and InnerAlloc...
pubrebind
template< class T >
struct rebind {
typedef scoped_allocator_adaptor<
std::allocator_traits<OuterAlloc>::template rebind_alloc<T>,
InnerAllocs...
> other;
};

Member functions

pub(constructor)creates a new scoped_allocator_adaptor instance
pub(destructor)destructs a scoped_allocator_adaptor instance
puboperator=assigns a scoped_allocator_adaptor
pubinner_allocatorobtains an inner_allocator reference
pubouter_allocatorobtains an outer_allocator reference
puballocateallocates uninitialized storage using the outer allocator
pubdeallocatedeallocates storage using the outer allocator
pubmax_sizereturns the largest allocation size supported by the outer allocator
pubconstructconstructs an object in allocated storage, passing the inner allocator to its constructor if appropriate
pubdestroydestructs an object in allocated storage
pubselect_on_container_copy_constructioncopies the state of scoped_allocator_adaptor and all its allocators

Non-member functions

puboperator==
operator!= (removed in C++20)
compares two scoped_allocator_adaptor instances
Deduction guides (since C++17)

Defined in header <scoped_allocator>

Since C++17
template<class OuterAlloc, class... InnerAllocs>
scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
-> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;

One deduction guide is provided for std::scoped_allocator_adaptor to make it possible to deduce its outer allocator.

Example

#include <vector>
#include <scoped_allocator>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/adaptive_pool.hpp>
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");
}

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DRApplied toBehavior as publishedCorrect behavior
LWG 2108C++11there was no way to show if scoped_allocator_adaptor is statelessis_always_equal provided

std::scoped_allocator_adaptor

Defined inscoped_allocator
Since C++11
template< class OuterAlloc, class... InnerAllocs >
class scoped_allocator_adaptor : public OuterAlloc;

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.

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.

Member types

pubTypeDefinition
pubouter_allocator_typeOuterAlloc
pubinner_allocator_typescoped_allocator_adaptor<InnerAllocs...> or, if sizeof...(InnerAllocs) == 0, scoped_allocator_adaptor<OuterAlloc>
pubvalue_type
std::allocator_traits<OuterAlloc>::value_type
pubsize_type
std::allocator_traits<OuterAlloc>::size_type
pubpointer
std::allocator_traits<OuterAlloc>::pointer
pubconst_pointer
std::allocator_traits<OuterAlloc>::const_pointer
pubconst_void_pointer
std::allocator_traits<OuterAlloc>::const_void_pointer
pubpropagate_on_container_copy_assignmentstd::true_type if std::allocator_traits<A>::propagate_on_container_copy_assignment::value is true for at least one allocator A among OuterAlloc and InnerAlloc...
pubpropagate_on_container_move_assignmentstd::true_type if std::allocator_traits<A>::propagate_on_container_move_assignment::value is true for at least one allocator A among OuterAlloc and InnerAlloc...
pubpropagate_on_container_swapstd::true_type if std::allocator_traits<A>::propagate_on_container_swap::value is true for at least one allocator A among OuterAlloc and InnerAlloc...
pubis_always_equalstd::true_type if std::allocator_traits<A>::propagate_on_container_swap::value is true for at least one allocator A among OuterAlloc and InnerAlloc...
pubrebind
template< class T >
struct rebind {
typedef scoped_allocator_adaptor<
std::allocator_traits<OuterAlloc>::template rebind_alloc<T>,
InnerAllocs...
> other;
};

Member functions

pub(constructor)creates a new scoped_allocator_adaptor instance
pub(destructor)destructs a scoped_allocator_adaptor instance
puboperator=assigns a scoped_allocator_adaptor
pubinner_allocatorobtains an inner_allocator reference
pubouter_allocatorobtains an outer_allocator reference
puballocateallocates uninitialized storage using the outer allocator
pubdeallocatedeallocates storage using the outer allocator
pubmax_sizereturns the largest allocation size supported by the outer allocator
pubconstructconstructs an object in allocated storage, passing the inner allocator to its constructor if appropriate
pubdestroydestructs an object in allocated storage
pubselect_on_container_copy_constructioncopies the state of scoped_allocator_adaptor and all its allocators

Non-member functions

puboperator==
operator!= (removed in C++20)
compares two scoped_allocator_adaptor instances
Deduction guides (since C++17)

Defined in header <scoped_allocator>

Since C++17
template<class OuterAlloc, class... InnerAllocs>
scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
-> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;

One deduction guide is provided for std::scoped_allocator_adaptor to make it possible to deduce its outer allocator.

Example

#include <vector>
#include <scoped_allocator>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/adaptive_pool.hpp>
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");
}

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DRApplied toBehavior as publishedCorrect behavior
LWG 2108C++11there was no way to show if scoped_allocator_adaptor is statelessis_always_equal provided