Modify

Ticket #6606 (closed Bugs: fixed)

Opened 2 years ago

Last modified 20 months ago

Map: rbtree_node doesn't use allocator_traits to construct m_data

Reported by: Erik Jensen <Erik.Jensen@…> Owned by: igaztanaga
Milestone: To Be Determined Component: container
Version: Boost 1.49.0 Severity: Problem
Keywords: Cc:

Description

I'm not at all sure what the best way to fix this is. The STL implementation that ships with the Visual Studio 11 preview calls allocate for the tree node and then construct for each of the members (the actual tree node constructor never gets called, as far as I can tell).

Attachments

Change History

comment:1 Changed 2 years ago by Erik Jensen <Erik.Jensen@…>

I guess another option would be to tuck a class like this (which I just made up) into your details, somewhere:

#include <boost/type_traits.hpp>
template <typename Ty, typename Alloc>
class allocator_constructed
{
public:
   template <typename T, typename Args...>
   allocator_constructed(const Alloc &alloc, Args &&...args)
      : _alloc(alloc)
   {
      allocator_traits<Alloc>::construct(_alloc,
         static_cast<Ty*>(static_cast<void*>(&data)),
         boost::forward<Args>(args)...);
   }
   ~manually_constructed() {
      allocator_traits<Alloc>::destroy(_alloc,
         static_cast<Ty*>(static_cast<void*>(&data)));
   }
   Ty& operator*() {
      return *static_cast<Ty*>(static_cast<void*>(&data));
   }
   const Ty& operator*() const {
      return *static_cast<Ty*>(static_cast<void*>(&data));
   }
   Ty* operator->() {
      return static_cast<Ty*>(static_cast<void*>(&data));
   }
   const Ty* operator->() const {
      return static_cast<Ty*>(static_cast<void*>(&data));
   }
private:
   Alloc _alloc;
   boost::aligned_storage<sizeof(Ty), std::alignment_of<Ty>::value> data;
};

And then have members of this class.

comment:2 Changed 2 years ago by Erik Jensen <Erik.Jensen@…>

One further note:

I was reading through the standard, and came across this (§23.2.1¶3):

For the components affected by this subclause that declare an allocator_type, objects stored in these components shall be constructed using the allocator_traits<allocator_type>::construct function and destroyed using the allocator_traits<allocator_type>::destroy function (20.6.8.2). These functions are called only for the container’s element type, not for internal types used by the container. [ Note: This means, for example, that a node-based container might need to construct nodes containing aligned buffers and call construct to place the element into the buffer. —end note ]

My understanding, then, is that while construct should be called for the pair, it should not be called for rbtree_node (which it currently is).

comment:3 Changed 20 months ago by igaztanaga

  • Status changed from new to closed
  • Resolution set to fixed

Fixed in Boost 1.50

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.