Relation between Allocator and NodeAllocator in a Container

Consider a singly-linked list container.
Being constructed with an alloc<T>, it will rebind it as alloc<node<T>> for internal use.

Question: is allocator_type the same as alloc<T> or as alloc<node<T>>?

Thanks.
Last edited on
A very good question, actually. Check out the std::list implementation to see how they solved it.

(Basically, the principle of least surprise holds. The user should be looking at an alloc<T>, but everything the class accepts should recognize it and automatically convert it to an alloc<node<T>> behind the scenes. There is a little more hoop jumping beyond that... but it is what it is.)

Good luck!
> Being constructed with an alloc<T>, it will rebind it as alloc<node<T>> for internal use.

Actuallly it will be rebound with
typename std::allocator_traits< alloc<T> >::template rebind_alloc< node<T> > for internal use.

If alloc<T> is std::allocator<T>, then this would be the same as std::allocator< node<T> >

For a user-defined allocator alloc<T>, the rebound allocator need not be alloc< node<T> >.


> is allocator_type the same as alloc<T> or as alloc<node<T>>?

alloc<T>

(node<T> is an opaque implementation detail which is not visible in the interface.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <typeinfo>
#include <cstdlib>
#include <memory>
#include <string>
#include <cxxabi.h> // GNU
#include <list>
#include <forward_list>
#include <map>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <iostream>
#include <type_traits>

template< typename T > std::string type_name() // GNU
{
    int status ;
    std::unique_ptr< char[], decltype(&std::free) > buffer(
        __cxxabiv1::__cxa_demangle( typeid(T).name(), nullptr, 0, &status ), &std::free ) ;
    return status==0 ? buffer.get() : "__cxa_demangle error" ;
}

#define show_type(a) ( std::cout << "type of " << #a << " is: " << type_name<a>() << '\n' )

int main()
{
    show_type( std::list<int>::allocator_type ) ;
    show_type( std::forward_list<double>::allocator_type ) ;
    
    using map_allocator_type = std::map<std::string,long>::allocator_type ;
    show_type( map_allocator_type ) ;
    
    using namespace boost::interprocess ;
    using my_allocator_type = allocator< int, managed_shared_memory::segment_manager > ;
    using my_list_type = std::list< int, my_allocator_type > ;
    show_type( my_list_type::allocator_type ) ;
    std::cout << "my_list_type::allocator_type is same as my_allocator_type? " << std::boolalpha 
              << std::is_same< my_list_type::allocator_type, my_allocator_type >::value << '\n' ; 
}

g++-4.8 -std=c++11 -O2 -Wall -Wextra -pedantic-errors main.cpp && ./a.out
type of std::list<int>::allocator_type is: std::allocator<int>
type of std::forward_list<double>::allocator_type is: std::allocator<double>
type of map_allocator_type is: std::allocator<std::pair<std::string const, long> >
type of my_list_type::allocator_type is: boost::interprocess::allocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index> >
my_list_type::allocator_type is same as my_allocator_type? true

http://coliru.stacked-crooked.com/a/ec16ca4e26514cb9
Topic archived. No new replies allowed.