[GSoC] Update on extend shared_ptr to support array

Fan You youfan.noey@gmail.com
Tue Mar 24 08:38:00 GMT 2015


Hello,

Here is a quick update of my work on extend shared_ptr to support
array.(Finished basic constructor/function, weak_ptr support) I am
getting familiar with libstdc++, and I'm trying to follow the coding
style as close as possible. If there is any problems, please let me
know! :-)

Also, I have few questions:

1. For all those entries list here
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4335.html#header.memory.synop>,
do I need to implement them one by one into <experimental/memory>? Or,
for those entries that can still be apply to shared_ptr array with no
problem, can I just use them by including <memory> ?


2. Do I need to do a specialization for weak_ptr in shared_ptr_base.h
to support shared_ptr_array? Even though the proposal didn't talk
about it, I think it's necessary and I also made a few attempts on it.
(its shown in the attachment)

Thanks!
-------------- next part --------------
diff --git a/bits/shared_ptr_base.h b/bits/shared_ptr_base.h
index 026c597..b552d3b 100644
--- a/bits/shared_ptr_base.h
+++ b/bits/shared_ptr_base.h
@@ -1,3 +1,5 @@
+#include <iostream>
+#define DEBUG std::cout<<"!!" << "\n"
 // shared_ptr and weak_ptr implementation details -*- C++ -*-
 
 // Copyright (C) 2007-2014 Free Software Foundation, Inc.
@@ -1175,6 +1177,85 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __shared_count<_Lp>  _M_refcount;    // Reference counter.
     };
 
+  //array support
+  template<typename _Tp, _Lock_policy _Lp>
+    class __shared_ptr<_Tp[], _Lp>
+    {
+    public:
+      using element_type = _Tp;
+
+      __shared_ptr() = default;
+
+      template<typename _Tp1>
+	explicit __shared_ptr(_Tp1* __p) 
+	: _M_ptr(__p), _M_refcount(__p, _M_del) // default deleter
+	{
+	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
+	  static_assert( !is_void<_Tp1>::value, "incomplete type" );
+	  static_assert( sizeof(_Tp1) > 0, "incomplete type" );
+	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
+	  std::cout << "array shared_ptr basic constructor" << "\n";
+	}
+
+      template<typename _Tp1, typename _Deleter>
+	__shared_ptr(_Tp1* __p, _Deleter __d)
+	: _M_ptr(__p), _M_refcount(__p, __d) // custom deleter
+	{
+	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
+	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
+	  std::cout << "array shared_ptr custom_deleter constructor" << "\n";
+	}
+
+      //TODO Alloc
+
+      template<typename _Tp1>
+	explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
+	: _M_refcount(__r._M_refcount)
+	{
+	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
+	  _M_ptr = __r._M_ptr;
+	}
+
+      ~__shared_ptr() = default;
+
+      //debug
+      void debug() {DEBUG;}
+
+      //observers
+      _Tp*
+      get() const noexcept
+      {return _M_ptr;}
+
+      long
+      use_count() const noexcept
+      { return _M_refcount._M_get_use_count(); }
+
+    protected:
+      struct _D_Deleter
+      {
+	void
+	operator()(_Tp const *__p)
+	{
+	  delete [] __p;
+	  std::cout << "array shared_ptr default destructor" << "\n";
+	}
+      };
+
+    private:
+      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
+
+      _Tp* _M_ptr;			 //ptr
+      _D_Deleter _M_del;		 //default destructor
+      __shared_count<_Lp> _M_refcount;	 //ref counter
+    };
+
 
   // 20.7.2.2.7 shared_ptr comparisons
   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
@@ -1334,6 +1415,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __shared_ptr<_Tp, _Lp>();
     }
 
+  //array support __weak_ptr
+  template<typename _Tp, _Lock_policy _Lp>
+    class __weak_ptr<_Tp[], _Lp>
+    {
+    public:
+      using element_type = _Tp[];
+
+      __weak_ptr() = default;
+      //TODO ...
+
+     template<typename _Tp1>
+       __weak_ptr<_Tp[]>&
+       operator=(const __shared_ptr<_Tp1[], _Lp>& __r) noexcept
+       {
+         _M_ptr = __r._M_ptr;
+         _M_refcount = __r._M_refcount;
+         return *this;
+       }
+
+      __shared_ptr<_Tp, _Lp>
+      lock() const noexcept
+      { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
+
+    private:
+      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
+
+      _Tp* _M_ptr;
+      __weak_count<_Lp> _M_refcount;
+    };
 
   template<typename _Tp, _Lock_policy _Lp>
     class __weak_ptr
diff --git a/experimental/memory b/experimental/memory
new file mode 100644
index 0000000..4c6e06c
--- /dev/null
+++ b/experimental/memory
@@ -0,0 +1,57 @@
+#include <memory>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v1 {
+
+  template<typename _Tp>
+    class shared_ptr;
+
+  template<typename _Tp>
+    class weak_ptr;
+
+  template<typename _Tp>
+    class shared_ptr : public __shared_ptr<_Tp>
+    {
+    public:
+      constexpr shared_ptr() noexcept = default;
+
+      template<typename _Tp1>
+	explicit shared_ptr(_Tp1* __p) : __shared_ptr<_Tp>(__p) { }
+
+      template<typename _Tp1, typename _Deleter> 
+	shared_ptr(_Tp1* __p, _Deleter __d)
+	: __shared_ptr<_Tp>(__p, __d) { }
+
+      //TODO
+
+      ~shared_ptr() = default;
+
+      shared_ptr& operator=(const shared_ptr<_Tp>& __r) = default;
+
+      //shared_ptr& operator=(shared_ptr&& r) noexcept = default;
+
+      template<typename _Tp1>
+	explicit shared_ptr(const weak_ptr<_Tp1>& __r)
+	: __shared_ptr<_Tp>(__r){ }
+
+    };
+
+  template<typename _Tp>
+    class weak_ptr : public __weak_ptr<_Tp>
+    {
+    public:
+      constexpr weak_ptr() noexcept = default;
+
+      weak_ptr&
+      operator=(const shared_ptr<_Tp>& __r) noexcept
+      {
+	this->__weak_ptr<_Tp>::operator=(__r);
+	return *this;
+      }
+    };
+}
+}
+}


More information about the Libstdc++ mailing list