This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Add std::unordered_* C++11 allocator support


On 6 April 2013 19:53, Jonathan Wakely wrote:
>
> I'm not very comfortable with the "mutable value type" part which
> accesses the stored value through a pointer to a different type. This
> violates strict aliasing rules and would also give the wrong result if
> users provide an explicit specialization of std::pair<int, Foo> which
> stores pair::second before pair::first, then tries to store that type
> in an unordered_map.  When a pair<const int, Foo>* is cast to
> pair<int, Foo>* the user's explicit specialization would not be used
> and the layout would be wrong.  Would it be possible to separate the
> C++11 allocator support from the new feature that attempts to reuse
> existing nodes?  Or maybe remove the mutable value type stuff so that
> nodes can be reused for unordered sets but not unordered maps?

For a non-assignable value_type we can reuse the node (but not the
value_type) by destroying and constructing a new value_type in place:

      __node_type*
      operator()(const __node_type* __n) const
      {
    if (_M_nodes)
      {
        __node_type* __node = _M_nodes;
        allocator_traits<A>::destroy(a, __node->_M_valptr());
        __try {
          allocator_traits<A>::construct(a, __node->_M_valptr(),
*__n->_M_valptr());
          // Construction didn't throw, we can unlink the node.
          _M_nodes = _M_nodes->_M_next();
          __node->_M_nxt = nullptr;
          return __node;
        } __catch (...) {
          // TODO deallocate node
          __throw_exception_again;
        }
      }
    return _M_h._M_allocate_node(__n->_M_v());
      }

This can be much less efficient than assignment if the value_type has
its own allocated memory, but I don't see any alternative. Casting
pair<const A,B>& to pair<A,B>& is not an option.

N.B. the code above


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]