How do you determine the size of the nodes created by a 'std::map' for use with 'boost::pool_allocator' (in a cross-platform way)?

后端 未结 2 1238
轮回少年
轮回少年 2020-12-18 06:51

UPDATE

Per comments, answer, and additional research, I have come to the conclusion that there is typically no difference between a set

相关标签:
2条回答
  • 2020-12-18 07:36

    The problem is that you don't know the internal type which set uses for nodes.

    While I haven't figured out how to determine this at compile time, you can write a tracing allocator which prints out the sizeof the node type when allocate is called, as in:

    template<typename T>
    struct SimpleAllocator : private std::allocator<T>
    {
        using value_type = T;
        using pointer = typename std::allocator<T>::pointer;
        using size_type = typename std::allocator<T>::size_type;
    
        pointer allocate(size_type n)
        {   
            std::cout << "Allocator sizeof(T)==" << sizeof(T) << '\n';
            return std::allocator<T>::allocate(n);
        }   
    
        void deallocate(pointer p, size_type n)
        { return std::allocator<T>::deallocate(p, n); }
    };
    

    And a little test program (I'm testing with sets of ints):

    std::set<int, std::less<int>, SimpleAllocator<int>> s;
    s.insert(2);
    

    On my system, I get output of:

    Allocator sizeof(T)==32

    0 讨论(0)
  • 2020-12-18 07:41

    There isn't a truly cross platform way to deduce what you are after, since every map implementation is unhappy in its own way, but generally it is the map node that will be allocated in the pool.

    This looks different for the different implementations of the standard library, so you code will have to #ifdef-ed for the different versions. With a fragility warning in place, here are the main ones for the g++/clang++/msc compilers and their std libs:

    // libstdc++
    boost::singleton_pool<boost::fast_pool_allocator_tag,
        sizeof(std::_Rb_tree_node<fast_map_obj::value_type>)>::purge_memory()
    
    // libc++
    boost::singleton_pool<boost::fast_pool_allocator_tag,
        sizeof(std::__tree_node<fast_map_obj::value_type, void*>)>::purge_memory()
    
    // msvc 2013 (incl. nov ctp)
    boost::singleton_pool<boost::fast_pool_allocator_tag,
        sizeof(fast_map_obj::_Node)>::purge_memory()
    

    Here are some useful links for finding the necessary defines:

    http://www.boost.org/doc/libs/1_55_0/boost/config/compiler/

    http://sourceforge.net/p/predef/wiki/Compilers/

    0 讨论(0)
提交回复
热议问题