[GSoC] Patches for shared_ptr array and polymorphic_allocator

2015-07-17 Thread Fan You
Hi,

According to 


Here is my implementation of

[8.2] Extend shared_ptr to support arrays

[8.3] Type-Erased allocator

Thanks,

Fan
#ifndef _GLIBCXX_MEMORY_RESOURCE
#define _GLIBCXX_MEMORY_RESOURCE 1

#include 
#include 
#include 
#include 
#include 

namespace std {
namespace experimental {
inline namespace fundamentals_v1 {
namespace pmr {
  // Decleartion
  class memory_resource;

  template 
class polymorphic_allocator;

  template 
class resource_adaptor_imp;

  template 
using resource_adaptor = resource_adaptor_imp<
  typename allocator_traits<_Alloc>::template rebind_alloc>;

  // Global memory resources
  memory_resource* new_delete_resource() noexcept;
  memory_resource* null_memory_resource() noexcept;

  // The default memory resource
  memory_resource* get_default_resource() noexcept;
  memory_resource* set_default_resource(memory_resource* __r) noexcept;

  // Standard memory resources

  // 8.5 Class memory_resource
  class memory_resource
  {
static constexpr size_t __max_align = alignof(max_align_t);

  public:
virtual ~memory_resource() { }

void* allocate(size_t __bytes,
		   size_t __alignment = __max_align)
{ return do_allocate(__bytes, __alignment); }

void deallocate(void* __p, size_t __bytes,
		size_t __alignment = __max_align)
{ return do_deallocate(__p, __bytes, __alignment); }

bool is_equal(const memory_resource& __other) const noexcept
{ return do_is_equal(__other); }

  protected:
virtual void*
do_allocate(size_t __bytes, size_t __alignment) = 0;

virtual void
do_deallocate(void* __p, size_t __bytes, size_t __alignment) = 0;

virtual bool
do_is_equal(const memory_resource& __other) const noexcept = 0;

  private:
friend memory_resource* set_default_resource(memory_resource*);
friend memory_resource* get_default_resource();

static std::atomic s_default_resource;
  };

  bool operator==(const memory_resource& __a,
		  const memory_resource& __b) noexcept
  { return &__a == &__b || __a.is_equal(__b); }

  bool operator!=(const memory_resource& __a,
		  const memory_resource& __b) noexcept
  { return !(__a == __b); }

  template 
class __constructor_helper_imp
{
  using dont_care_type = bool;

public:
  // Construct with no allocator
  template 
	__constructor_helper_imp(false_type, _Args&&... __args)
  	: _M_tp(std::forward<_Args>(__args)...) { }

  // Construct with allocator
  // 1. uses_allocator == false
  // 1.1 no pair construction - ignore allocator
  template 
	__constructor_helper_imp(allocator_arg_t,
 const _Alloc& __a,
 false_type,
 dont_care_type,
 dont_care_type,
 _Args&&... __args)
  	: _M_tp(std::forward<_Args>(__args)...) { }

  // 2. uses_allocator == true && prepend allocator argument
  template 
	__constructor_helper_imp(allocator_arg_t,
 const _Alloc& __a,
 true_type,
 dont_care_type,
 true_type,
 _Args&&... __args)
  	: _M_tp(allocator_arg, __a, std::forward<_Args>(__args)...) { }

  // 3. uses_allocator == true && append allocator argument
  template 
	__constructor_helper_imp(allocator_arg_t,
 const _Alloc& __a,
 true_type,
 true_type,
 dont_care_type,
 _Args&&... __args)
  	: _M_tp(std::forward<_Args>(__args)..., __a) { }

  // 4. ill-formed
  template 
	__constructor_helper_imp(allocator_arg_t,
 const _Alloc& __a,
 true_type,
 false_type,
 false_type,
 _Args&&... __args)
  	: _M_tp(std::forward<_Args>(__args)...)
	{
	  static_assert(sizeof(_Alloc) == 0,
			"Type uses an allocator but "
			"allocator-aware constructor "
			"is missing");
	}

private:
  _Tp _M_tp;
};

  template 
class __constructor_helper : private __constructor_helper_imp<_Tp>
{
  using _Base = __constructor_helper_imp<_Tp>;

public:
  template 
	__constructor_helper(allocator_arg_t, _Alloc&& __a, _Args&&... __args)
  	: _Base(allocator_arg, __a,
  	uses_allocator<_Tp, _Alloc>(),
  	is_constructible<_Tp, _Args..., _Alloc>(),
  	is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>(),
  	std::forward<_Args>(__args)...)
  	{ }

  template 
	__constructor_helper(_Args&&... __args)
	: _Base(false_type(), std::forward<_Args>(__args)...)
	{ }

};

  // 8.6 Class template polymorphic_allocator
  template 
class polymorphic_allocator
{
  using __uses_alloc1_ = __uses_alloc1;
  using __uses_alloc2_ = __uses_alloc2;

public:
  using value_type = _Tp;

  polymorphic_allocator() noexcept
  : _M_resource(get_default_resource())
  { } // used here

  polymorphic_allocator(memory_resource* __r)
  : _M_resource(__r ? __r : get_default_resource())
  { }

  polymorphic_allocator(const polymorphic_allocator& __other) = defau

Fwd: [PATCH][GSoC] Extend shared_ptr to support arrays

2015-06-11 Thread Fan You
Hi,

This is my first patch for GSoC project: extend shared_ptr to support arrays.

Changes are made in these files:

* libstdc++-v3/include/bits/shared_ptr_base.h : Renamed
_Sp_counted_deleter to _Sp_counted_array, changed _shared_count
construct from _Sp_counted_ptr to _Sp_counted_array. Added
specialization for __shared_ptr and __weak_ptr to support array.

* libstdc++-v3/include/experimental/memory : add shared_ptr into fundamentals_v1

Is it too long for reviewing? Should I detach them into different
patches? Any comments?

Thanks,

Fan


a.patch
Description: Binary data


Re: [PATCH][GSoC] Extend shared_ptr to support arrays

2015-06-24 Thread Fan You
Hi,

Here is the revised patch including all the test case.

This can also be seen at  on branch


Any comments?

2015-06-23 12:19 GMT+08:00 Tim Shen :
> On Sun, Jun 21, 2015 at 3:50 AM, Tim Shen  wrote:
>> Quickly looked at __shared_ptr<__libfund_v1<_Tp>, _Lp>; will look at
>> the rest parts later.
>
> All suggestions apply for all occursions, not just for the quoted code.
>
> +  // helpers for std::experimental::enable_shared_from_this
> +
> +  template
> +struct __helper_for_experimental_enable_shared
> +{
> +  void _Call_M_assign(__weak_ptr<__libfund_v1<_Tp>, _Lp>& __wp,
> + _Tp* __ptr,
> + const __shared_count<_Lp>& __refcount)
> +   { __wp._M_assign(__ptr, __refcount); }
> +};
> Make the function it static; Suggested class name: __weak_ptr_friend,
> function name _S_assign.
>
> +  // Used by __enable_shared_from_this.
> +  void
> +  _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
> +  {
> +   _M_ptr = __ptr;
> +   _M_refcount = __refcount;
> +  }
> element_type* __ptr?
>
> Also need a _Compatible; possible implementation:
>
> template
>   struct __sp_compatible_helper
>   {  static constexpr bool value = std::is_convertible<_From_type*,
> _To_type*>::value;  };
>
> template
>   struct __sp_compatible_helper<_Tp[_Nm], _Tp[]>
>   { static constexpr bool value = true; };
>
> ...
>
> template
>   using _Compatible = typename std::enable_if<__sp_compatible<_Tp1,
> _Tp>::value>::type;
>
> +   template
> + inline bool
> + operator<(const shared_ptr<_Tp1>& __a,
> +  const shared_ptr<_Tp2>& __b) noexcept
> + {
> +   using _Tp1_RE = typename remove_extent<_Tp1>::type;
> +   using _Tp2_RE = typename remove_extent<_Tp2>::type;
> +   using _CT = typename std::common_type<_Tp1_RE*, _Tp2_RE*>::type;
> +   return std::less<_CT>()(__a.get(), __b.get());
> + }
> using _Tp1_RE = typename shared_ptr<_Tp1>::element_type;
>
> +   // 8.2.1.3, shared_ptr casts
> +   template
> + inline shared_ptr<_Tp>
> + static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
> + { shared_ptr<_Tp>(__r, static_cast shared_ptr<_Tp>::element_type*>(__r.get())); }
> +
> Missing "return". You can turn on -Wsystem-headers to check for warnings.
>
>
> --
> Regards,
> Tim Shen


a
Description: Binary data