[GSoC] Extend shared_ptr to support arrays
Fan You
youfan.noey@gmail.com
Mon Mar 16 19:14:00 GMT 2015
Hello,
It's my simple version of extending shared_ptr to support arrays, am I
in the right direction?
When I do the boundary checking, when user try to access elements that
are out of boundary, should I throw an exception or just use assert to
avoid that from happening? (I saw boost use BOOST_ASSERT to do that)
Next, my plan for GSoC is to finish shared_ptr_array_support first and
then choose one or two from other TS.
For those TS I am looking into:
- Invocation type traits
I have a very limited compiler knowledge, so I am still learning it.
- Polymorphic Memory Resources
After reading the proposal
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3916.pdf>, I
am still not quite sure about the idea of Polymorphic memory
resources. The example on page 5 make sense to me, but what's the key
different between the original memory allocation method and this? Any
other resource that I can read from?
- Networking TS
I get the wrong link last time, but I find it myself(don't know if
it's correct <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html>).
The proposal intend to implement a whole Network Library and it's
currently too big for me to read them all. Can you suggest a specific
part of it that I should start looking at or working on?
Is it OK and realistic to propose multiple TS in GSoC? Any suggestion
or critic are welcome!
Thanks,
Fan
-------------- next part --------------
diff --git a/bits/shared_ptr.h b/bits/shared_ptr.h
index 081d3bd..d5f6e1c 100644
--- a/bits/shared_ptr.h
+++ b/bits/shared_ptr.h
@@ -614,9 +614,182 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return std::hash<_Tp*>()(__s.get()); }
};
- // @} group pointer_abstractions
+ /// specialization for shared_ptr_array
-_GLIBCXX_END_NAMESPACE_VERSION
+ //dynamic size
+ template<typename _Tp>
+ class shared_ptr<_Tp[]> : public __shared_ptr<_Tp>{
+ public:
+ constexpr shared_ptr<_Tp[]>() noexcept :
+ __shared_ptr<_Tp>() { }
+
+ template<typename _Tp1>
+ explicit shared_ptr<_Tp[]>(_Tp1* __p) :
+ __shared_ptr<_Tp>(__p, _A_Del) { }
+
+ template<typename _Tp1, typename _Deleter>
+ shared_ptr<_Tp[]>(_Tp1* __p, _Deleter __d) :
+ __shared_ptr<_Tp>(__p, __d) { }
+
+ template<typename _Deleter>
+ shared_ptr<_Tp[]>(nullptr_t __p, _Deleter __d) :
+ __shared_ptr<_Tp>(__p, __d) { }
+
+ template<typename _Tp1, typename _Deleter, typename _Alloc>
+ shared_ptr<_Tp[]>(_Tp1* __p, _Deleter __d, _Alloc __a):
+ __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
+
+ template<typename _Deleter, typename _Alloc>
+ shared_ptr<_Tp[]>(nullptr_t __p, _Deleter __d, _Alloc __a):
+ __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
+
+ template<typename _Tp1>
+ shared_ptr<_Tp[]>(const shared_ptr<_Tp1[]>& __r, _Tp* __p) noexcept :
+ __shared_ptr<_Tp>(__r, __p) { }
+
+ template<typename _Tp1, typename = typename
+ std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
+ shared_ptr<_Tp[]>(const shared_ptr<_Tp1[]>& __r) noexcept :
+ __shared_ptr<_Tp>(__r) { }
+
+ shared_ptr<_Tp[]>(shared_ptr<_Tp[]>& __r) = default;
+
+ //shared_ptr<_Tp[]>(shared_ptr<_Tp[]>&& __r) noexcept :
+ // __shared_ptr<_Tp>(std::move(__r)) { }
+
+ template<typename _Tp1, typename = typename
+ std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
+ shared_ptr<_Tp[]>(shared_ptr<_Tp1[]>&& __r) noexcept
+ : __shared_ptr<_Tp>(std::move(__r)) { }
+
+#if _GLIBCXX_USE_DEPRECATED
+ template<typename _Tp1>
+ shared_ptr<_Tp[]>(std::auto_ptr<_Tp1>&& __r); // TODO auto_ptr still calls delete p;
+#endif
+
+ template<typename _Tp1, typename _Del>
+ shared_ptr<_Tp[]>(std::unique_ptr<_Tp1[], _Del>&& __r) :
+ __shared_ptr<_Tp>(std::move(__r)) { }
+
+ constexpr shared_ptr<_Tp[]>(nullptr_t __p) noexcept :
+ __shared_ptr<_Tp>(__p) { }
+
+#if _GLIBCXX_USE_DEPRECATED
+ //TODO
+#endif
+
+ shared_ptr<_Tp[]>& operator=(const shared_ptr<_Tp[]>&) noexcept = default;
+
+ template<typename _Tp1>
+ shared_ptr<_Tp[]>&
+ operator=(const shared_ptr<_Tp1[]>& __r) noexcept {
+ this->__shared_ptr<_Tp>::operator=(__r);
+ return *this;
+ }
+
+ shared_ptr<_Tp[]>&
+ operator=(shared_ptr<_Tp[]>&& __r) noexcept
+ {
+ this->__shared_ptr<_Tp>::operator=(std::move(__r));
+ return *this;
+ }
+
+ template<typename _Tp1, typename _Del>
+ shared_ptr<_Tp[]>&
+ operator=(std::unique_ptr<_Tp1[], _Del>&& __r)
+ {
+ this->__shared_ptr<_Tp>::operator=(std::move(__r));
+ return *this;
+ }
+
+ // access element in array
+ typename std::add_lvalue_reference<_Tp>::type
+ operator[](size_t __i) const{
+ return (this->get())[__i];
+ }
+
+ protected:
+ struct _Deleter {
+ void operator()(_Tp const *p) {
+ delete [] p;
+ }
+ };
+
+ private:
+ _Deleter _A_Del;
+ };
+
+ // fix size TODO
+ template<typename _Tp, std::size_t _num>
+ class shared_ptr<_Tp[_num]> : public shared_ptr<_Tp[]> {
+ public:
+ constexpr shared_ptr<_Tp[_num]>() noexcept :
+ shared_ptr<_Tp[]>() { }
+
+ template<typename _Tp1>
+ explicit shared_ptr<_Tp[_num]>(_Tp1* __p) :
+ shared_ptr<_Tp[]>(__p) { }
+
+ template<typename _Tp1, typename _Deleter>
+ shared_ptr<_Tp[_num]>(_Tp1* __p, _Deleter __d) :
+ shared_ptr<_Tp[]>(__p, __d) { }
+
+ template<typename _Deleter>
+ shared_ptr<_Tp[_num]>(nullptr_t __p, _Deleter __d) :
+ shared_ptr<_Tp[]>(__p, __d) { }
+
+ template<typename _Tp1, typename _Deleter, typename _Alloc>
+ shared_ptr<_Tp[_num]>(_Tp1* __p, _Deleter __d, _Alloc __a):
+ shared_ptr<_Tp[]>(__p, __d, std::move(__a)) { }
+
+ template<typename _Deleter, typename _Alloc>
+ shared_ptr<_Tp[_num]>(nullptr_t __p, _Deleter __d, _Alloc __a):
+ shared_ptr<_Tp[]>(__p, __d, std::move(__a)) { }
+
+ template<typename _Tp1>
+ shared_ptr<_Tp[_num]>(const shared_ptr<_Tp1[_num]>& __r, _Tp* __p) noexcept : // or _Tp1[]
+ shared_ptr<_Tp[]>(__r, __p) { }
+
+ template<typename _Tp1, typename = typename
+ std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
+ shared_ptr<_Tp[_num]>(const shared_ptr<_Tp1[_num]>& __r) noexcept : // or _Tp1[]
+ shared_ptr<_Tp[]>(__r) { }
+
+ shared_ptr<_Tp[_num]>(shared_ptr<_Tp[_num]>& __r) = default; // or _Tp1[]
+
+ //shared_ptr<_Tp[_num]>(shared_ptr<_Tp[_num]>&& __r) noexcept :
+ // __shared_ptr<_Tp>(std::move(__r)) { }
+
+ template<typename _Tp1, typename = typename
+ std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
+ shared_ptr<_Tp[_num]>(shared_ptr<_Tp1[]>&& __r) noexcept // or _Tp1[]
+ : shared_ptr<_Tp[]>(std::move(__r)) { }
+
+#if _GLIBCXX_USE_DEPRECATED
+ template<typename _Tp1>
+ shared_ptr<_Tp[_num]>(std::auto_ptr<_Tp1>&& __r); // TODO auto_ptr still calls delete p;
+#endif
+
+ template<typename _Tp1, typename _Del>
+ shared_ptr<_Tp[_num]>(std::unique_ptr<_Tp1[], _Del>&& __r) :
+ shared_ptr<_Tp[]>(std::move(__r)) { }
+
+ constexpr shared_ptr<_Tp[_num]>(nullptr_t __p) noexcept :
+ shared_ptr<_Tp[]>(__p) { }
+
+ typename std::add_lvalue_reference<_Tp>::type
+ operator[](size_t __i) const{
+ if(__i >= _num) {
+ throw;
+ }else {
+ return (this->get())[__i];
+ }
+ }
+ };
+
+ // @} group pointer_abstractions
+
+ _GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _SHARED_PTR_H
More information about the Libstdc++
mailing list