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: [v3] Implement pointer_traits and allocator_traits


Here's a patch to make shared_ptr use allocator_traits, I don't plan
to commit this (at least not yet) but it shows what's needed to use
allocator_traits instead of the C++03 way of doing things.  It uses
allocator_traits<T>::__rebind<U>::__type which is a temporary
substitute for the unsupported allocator_traits<T>::rebind<U> template
alias.

This patch isn't quite backward compatible, because I changed
_Sp_counted_deleter::_My_deleter to derive from the supplied _Alloc
type instead of the rebound type.  I think that's more correct, but
changes the type (and possibly size) of the _M_del member.  The safe
way to make that change is probably to rename _Sp_counted_deleter to
_Sp_counted_deleter2, so that code built against the old header uses
the old type and code built with the new header uses a new, distinct
type.

I completely rewrote _Sp_counted_ptr_inplace because it doesn't need a
deleter, so doesn't need to derive from _Sp_counted_deleter and can
benefit from the EBO. That could be renamed _Sp_counted_ptr_inplace2
for compatibility.

Apart from demonstrating how to make use of allocator_traits to
support both C++03 and C++11 allocators, this patch allows the
following example to work, using allocate_shared to create a
shared_ptr to a type with no public constructors or destructor, by
using a custom allocator which is declared as a friend:

#include <memory>
#include <new>

template<typename T>
struct MyAlloc;

class Private
{
  Private() = default;
  Private(const Private&) = default;
  ~Private() = default;

  friend class MyAlloc<Private>;

public:
  int get() const { return 0; }
};

template<typename T>
struct MyAlloc : std::allocator<Private>
{
  void construct(void* p) { ::new(p) Private(); }
};

int main()
{
  MyAlloc<Private> a;
  auto p = std::allocate_shared<Private>(a);
  return p->get();
}

This allows you to write types which can only be managed

Attachment: sp-alloc.txt
Description: Text document


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