[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