[cfe-commits] [libcxx] r147437 - /libcxx/trunk/include/memory

Howard Hinnant hhinnant at apple.com
Mon Jan 2 09:56:02 PST 2012


Author: hhinnant
Date: Mon Jan  2 11:56:02 2012
New Revision: 147437

URL: http://llvm.org/viewvc/llvm-project?rev=147437&view=rev
Log:
1.  Fix make_shared<const T>.  2.  Allow allocator<const T> as an extension.  3.  Refactor work which fixed unique_ptr<const T[]>.  4.  Remove no-longer-needed private declarations from unique_ptr.  5.  Add constraints to some shared_ptr and weak_ptr constructors and assignment operators so that is_constructible/is_assignable give the correct answers for shared_ptr and weak_ptr.  6.  Make defensive preparations in the shared_ptr free functions for the introduction of shared_ptr<T[]> in the future.  7.  As an optimization, add move constructor and move assignment to weak_ptr.

Modified:
    libcxx/trunk/include/memory

Modified: libcxx/trunk/include/memory
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=147437&r1=147436&r2=147437&view=diff
==============================================================================
--- libcxx/trunk/include/memory (original)
+++ libcxx/trunk/include/memory Mon Jan  2 11:56:02 2012
@@ -1677,6 +1677,114 @@
     _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
 };
 
+template <class _Tp>
+class _LIBCPP_VISIBLE allocator<const _Tp>
+{
+public:
+    typedef size_t            size_type;
+    typedef ptrdiff_t         difference_type;
+    typedef const _Tp*        pointer;
+    typedef const _Tp*        const_pointer;
+    typedef const _Tp&        reference;
+    typedef const _Tp&        const_reference;
+    typedef _Tp               value_type;
+
+    typedef true_type propagate_on_container_move_assignment;
+
+    template <class _Up> struct rebind {typedef allocator<_Up> other;};
+
+    _LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}
+    template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
+        {return _VSTD::addressof(__x);}
+    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
+        {return static_cast<pointer>(::operator new(__n * sizeof(_Tp)));}
+    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
+        {::operator delete((void*)__p);}
+    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
+        {return size_type(~0) / sizeof(_Tp);}
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class _Up, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(_Up* __p, _Args&&... __args)
+        {
+            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
+        }
+#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p)
+        {
+            ::new((void*)__p) _Tp();
+        }
+# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+    template <class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            !is_convertible<_A0, __rv<_A0> >::value,
+            void
+        >::type
+        construct(pointer __p, _A0& __a0)
+        {
+            ::new((void*)__p) _Tp(__a0);
+        }
+    template <class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            !is_convertible<_A0, __rv<_A0> >::value,
+            void
+        >::type
+        construct(pointer __p, const _A0& __a0)
+        {
+            ::new((void*)__p) _Tp(__a0);
+        }
+    template <class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            is_convertible<_A0, __rv<_A0> >::value,
+            void
+        >::type
+        construct(pointer __p, _A0 __a0)
+        {
+            ::new((void*)__p) _Tp(_VSTD::move(__a0));
+        }
+# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, _A0& __a0, _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, const _A0& __a0, _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, _A0& __a0, const _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, const _A0& __a0, const _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
+};
+
 template <class _Tp, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY
 bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
@@ -1838,9 +1946,9 @@
     typedef const typename remove_reference<_T2>::type& _T2_const_reference;
 
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1, int = 0)
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
         : __first_(_VSTD::forward<_T1_param>(__t1)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2, int* = 0)
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
         : __second_(_VSTD::forward<_T2_param>(__t2)) {}
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
         : __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
@@ -1935,9 +2043,9 @@
     typedef const typename remove_reference<_T2>::type& _T2_const_reference;
 
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1, int = 0)
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
         : _T1(_VSTD::forward<_T1_param>(__t1)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2, int* = 0)
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
         : __second_(_VSTD::forward<_T2_param>(__t2)) {}
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
         : _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
@@ -2216,9 +2324,9 @@
     typedef typename base::_T2_const_reference _T2_const_reference;
 
     _LIBCPP_INLINE_VISIBILITY __compressed_pair() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1, int = 0)
+    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1)
         : base(_VSTD::forward<_T1_param>(__t1)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2, int* = 0)
+    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2)
         : base(_VSTD::forward<_T2_param>(__t2)) {}
     _LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2)
         : base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {}
@@ -2262,7 +2370,7 @@
         _LIBCPP_INLINE_VISIBILITY
         __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
                                                       tuple<_Args2...> __second_args)
-            : base(__pc, __first_args, __second_args,
+            : base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
                    typename __make_tuple_indices<sizeof...(_Args1)>::type(),
                    typename __make_tuple_indices<sizeof...(_Args2) >::type())
             {}
@@ -2293,6 +2401,31 @@
                    __is_nothrow_swappable<_T1>::value)
     {__x.swap(__y);}
 
+// __same_or_less_cv_qualified
+
+template <class _Ptr1, class _Ptr2,
+          bool = is_same<typename remove_cv<typename pointer_traits<_Ptr1>::element_type>::type,
+                         typename remove_cv<typename pointer_traits<_Ptr2>::element_type>::type
+                        >::value
+         >
+struct __same_or_less_cv_qualified_imp
+    : is_convertible<_Ptr1, _Ptr2> {};
+
+template <class _Ptr1, class _Ptr2>
+struct __same_or_less_cv_qualified_imp<_Ptr1, _Ptr2, false>
+    : false_type {};
+
+template <class _Ptr1, class _Ptr2, bool = is_scalar<_Ptr1>::value &&
+                                         !is_pointer<_Ptr1>::value>
+struct __same_or_less_cv_qualified
+    : __same_or_less_cv_qualified_imp<_Ptr1, _Ptr2> {};
+
+template <class _Ptr1, class _Ptr2>
+struct __same_or_less_cv_qualified<_Ptr1, _Ptr2, true>
+    : false_type {};
+
+// default_delete
+
 template <class _Tp>
 struct _LIBCPP_VISIBLE default_delete
 {
@@ -2310,33 +2443,15 @@
 template <class _Tp>
 struct _LIBCPP_VISIBLE default_delete<_Tp[]>
 {
-private:
-    template <class _P1,
-              bool = is_same<typename remove_cv<typename pointer_traits<_P1>::element_type>::type,
-                             typename remove_cv<_Tp>::type>::value>
-    struct __same_or_less_cv_qualified_imp
-        : is_convertible<_P1, _Tp*> {};
-    template <class _P1>
-    struct __same_or_less_cv_qualified_imp<_P1, false>
-        : false_type {};
-    
-    template <class _P1, bool = is_scalar<_P1>::value && !is_pointer<_P1>::value>
-    struct __same_or_less_cv_qualified
-        : __same_or_less_cv_qualified_imp<_P1> {};
-    
-    template <class _P1>
-    struct __same_or_less_cv_qualified<_P1, true>
-        : false_type {};
-
 public:
     _LIBCPP_INLINE_VISIBILITY default_delete() _NOEXCEPT {}
     template <class _Up>
         _LIBCPP_INLINE_VISIBILITY default_delete(const default_delete<_Up[]>&,
-             typename enable_if<__same_or_less_cv_qualified<_Up*>::value>::type* = 0) _NOEXCEPT {}
+             typename enable_if<__same_or_less_cv_qualified<_Up*, _Tp*>::value>::type* = 0) _NOEXCEPT {}
     template <class _Up>
         _LIBCPP_INLINE_VISIBILITY
         void operator() (_Up* __ptr,
-                         typename enable_if<__same_or_less_cv_qualified<_Up*>::value>::type* = 0) const _NOEXCEPT
+                         typename enable_if<__same_or_less_cv_qualified<_Up*, _Tp*>::value>::type* = 0) const _NOEXCEPT
         {
             static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type");
             delete [] __ptr;
@@ -2353,14 +2468,7 @@
 private:
     __compressed_pair<pointer, deleter_type> __ptr_;
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    unique_ptr(const unique_ptr&);
-    unique_ptr& operator=(const unique_ptr&);
-    template <class _Up, class _Ep>
-        unique_ptr(const unique_ptr<_Up, _Ep>&);
-    template <class _Up, class _Ep>
-        unique_ptr& operator=(const unique_ptr<_Up, _Ep>&);
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     unique_ptr(unique_ptr&);
     template <class _Up, class _Ep>
         unique_ptr(unique_ptr<_Up, _Ep>&);
@@ -2447,7 +2555,9 @@
             _LIBCPP_INLINE_VISIBILITY
             typename enable_if
             <
-                !is_array<_Up>::value,
+                !is_array<_Up>::value &&
+                is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&
+                is_assignable<deleter_type&, _Ep&&>::value,
                 unique_ptr&
             >::type
             operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
@@ -2537,28 +2647,7 @@
 private:
     __compressed_pair<pointer, deleter_type> __ptr_;
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    unique_ptr(const unique_ptr&);
-    unique_ptr& operator=(const unique_ptr&);
-
-    template <class _P1,
-              bool = is_same<typename remove_cv<typename pointer_traits<_P1>::element_type>::type,
-                             typename remove_cv<element_type>::type>::value>
-    struct __same_or_less_cv_qualified_imp
-        : is_convertible<_P1, pointer> {};
-    template <class _P1>
-    struct __same_or_less_cv_qualified_imp<_P1, false>
-        : false_type {};
-    
-    template <class _P1, bool = is_scalar<_P1>::value && !is_pointer<_P1>::value>
-    struct __same_or_less_cv_qualified
-        : __same_or_less_cv_qualified_imp<_P1> {};
-    
-    template <class _P1>
-    struct __same_or_less_cv_qualified<_P1, true>
-        : false_type {};
-
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     unique_ptr(unique_ptr&);
     template <class _Up>
         unique_ptr(unique_ptr<_Up>&);
@@ -2586,7 +2675,7 @@
         }
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     template <class _Pp,
-              class = typename enable_if<__same_or_less_cv_qualified<_Pp>::value>::type
+              class = typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value>::type
              >
     _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(_Pp __p) _NOEXCEPT
         : __ptr_(__p)
@@ -2596,7 +2685,7 @@
         }
 
     template <class _Pp,
-              class = typename enable_if<__same_or_less_cv_qualified<_Pp>::value>::type
+              class = typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value>::type
              >
     _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p, typename conditional<
                                        is_reference<deleter_type>::value,
@@ -2613,8 +2702,7 @@
         : __ptr_(pointer(), __d) {}
 
     template <class _Pp,
-              class = typename enable_if<__same_or_less_cv_qualified<_Pp>::value ||
-                                         is_same<_Pp, nullptr_t>::value>::type
+              class = typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value>::type
              >
     _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p, typename remove_reference<deleter_type>::type&& __d)
              _NOEXCEPT
@@ -2646,7 +2734,7 @@
                    typename enable_if
                             <
                                 is_array<_Up>::value &&
-                                __same_or_less_cv_qualified<typename unique_ptr<_Up, _Ep>::pointer>::value
+                                __same_or_less_cv_qualified<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value
                                 && is_convertible<_Ep, deleter_type>::value &&
                                 (
                                     !is_reference<deleter_type>::value ||
@@ -2663,8 +2751,8 @@
             typename enable_if
             <
                 is_array<_Up>::value &&
-                __same_or_less_cv_qualified<typename unique_ptr<_Up, _Ep>::pointer>::value &&
-                is_assignable<deleter_type, _Ep>::value,
+                __same_or_less_cv_qualified<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&
+                is_assignable<deleter_type&, _Ep&&>::value,
                 unique_ptr&
             >::type
             operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
@@ -2731,7 +2819,7 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     template <class _Pp,
-              class = typename enable_if<__same_or_less_cv_qualified<_Pp>::value>::type
+              class = typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value>::type
              >
     _LIBCPP_INLINE_VISIBILITY void reset(_Pp __p) _NOEXCEPT
     {
@@ -3492,9 +3580,27 @@
 public:
     shared_ptr() _NOEXCEPT;
     shared_ptr(nullptr_t) _NOEXCEPT;
-    template<class _Yp> explicit shared_ptr(_Yp* __p);
-    template<class _Yp, class _Dp> shared_ptr(_Yp* __p, _Dp __d);
-    template<class _Yp, class _Dp, class _Alloc> shared_ptr(_Yp* __p, _Dp __d, _Alloc __a);
+    template<class _Yp,
+             class = typename enable_if
+                     <
+                        is_convertible<_Yp*, element_type*>::value
+                     >::type
+            >
+        explicit shared_ptr(_Yp* __p);
+    template<class _Yp, class _Dp,
+             class = typename enable_if
+                     <
+                        is_convertible<_Yp*, element_type*>::value
+                     >::type
+            >
+        shared_ptr(_Yp* __p, _Dp __d);
+    template<class _Yp, class _Dp, class _Alloc,
+             class = typename enable_if
+                     <
+                        is_convertible<_Yp*, element_type*>::value
+                     >::type
+            >
+        shared_ptr(_Yp* __p, _Dp __d, _Alloc __a);
     template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
     template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
     template<class _Yp> shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
@@ -3512,50 +3618,134 @@
     template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
                    typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type= __nat());
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    template<class _Yp> shared_ptr(auto_ptr<_Yp>&& __r);
+    template<class _Yp,
+             class = typename enable_if
+                     <
+                        is_convertible<_Yp*, element_type*>::value
+                     >::type
+            >
+        shared_ptr(auto_ptr<_Yp>&& __r);
 #else
-    template<class _Yp> shared_ptr(auto_ptr<_Yp> __r);
+    template<class _Yp,
+             class = typename enable_if
+                     <
+                        is_convertible<_Yp*, element_type*>::value
+                     >::type
+            >
+        shared_ptr(auto_ptr<_Yp> __r);
 #endif
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-private:
-    template <class _Yp, class _Dp> shared_ptr(const unique_ptr<_Yp, _Dp>& __r);// = delete;
-public:
-    template <class _Yp, class _Dp> shared_ptr(unique_ptr<_Yp, _Dp>&&,
+    template <class _Yp, class _Dp,
+                 class = typename enable_if
+                 <
+                    !is_array<_Yp>::value &&
+                    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
+                 >::type
+             >
+       shared_ptr(unique_ptr<_Yp, _Dp>&&,
        typename enable_if<!is_lvalue_reference<_Dp>::value, __nat>::type = __nat());
-    template <class _Yp, class _Dp> shared_ptr(unique_ptr<_Yp, _Dp>&&,
+    template <class _Yp, class _Dp,
+                 class = typename enable_if
+                 <
+                    !is_array<_Yp>::value &&
+                    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
+                 >::type
+             >
+       shared_ptr(unique_ptr<_Yp, _Dp>&&,
        typename enable_if<is_lvalue_reference<_Dp>::value, __nat>::type = __nat());
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    template <class _Yp, class _Dp> shared_ptr(unique_ptr<_Yp, _Dp>,
+    template <class _Yp, class _Dp,
+                 class = typename enable_if
+                 <
+                    !is_array<_Yp>::value &&
+                    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
+                 >::type
+             > shared_ptr(unique_ptr<_Yp, _Dp>,
        typename enable_if<!is_lvalue_reference<_Dp>::value, __nat>::type = __nat());
-    template <class _Yp, class _Dp> shared_ptr(unique_ptr<_Yp, _Dp>,
+    template <class _Yp, class _Dp,
+                 class = typename enable_if
+                 <
+                    !is_array<_Yp>::value &&
+                    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
+                 >::type
+             >
+       shared_ptr(unique_ptr<_Yp, _Dp>,
        typename enable_if<is_lvalue_reference<_Dp>::value, __nat>::type = __nat());
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
     ~shared_ptr();
 
     shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
-    template<class _Yp> shared_ptr& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr&
+        >::type
+        operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
-    template<class _Yp> shared_ptr& operator=(shared_ptr<_Yp>&& __r);
-    template<class _Yp> shared_ptr& operator=(auto_ptr<_Yp>&& __r);
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr<_Tp>&
+        >::type
+        operator=(shared_ptr<_Yp>&& __r);
+    template<class _Yp>
+        typename enable_if
+        <
+            !is_array<_Yp>::value &&
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr&
+        >::type
+        operator=(auto_ptr<_Yp>&& __r);
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    template<class _Yp> shared_ptr& operator=(auto_ptr<_Yp> __r);
+    template<class _Yp>
+        typename enable_if
+        <
+            !is_array<_Yp>::value &&
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr&
+        >::type
+        operator=(auto_ptr<_Yp> __r);
 #endif
+    template <class _Yp, class _Dp>
+        typename enable_if
+        <
+            !is_array<_Yp>::value &&
+            is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+            shared_ptr&
+        >::type
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-private:
-    template <class _Yp, class _Dp> shared_ptr& operator=(const unique_ptr<_Yp, _Dp>& __r);// = delete;
-public:
-    template <class _Yp, class _Dp> shared_ptr& operator=(unique_ptr<_Yp, _Dp>&& __r);
+        operator=(unique_ptr<_Yp, _Dp>&& __r);
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    template <class _Yp, class _Dp> shared_ptr& operator=(unique_ptr<_Yp, _Dp> __r);
+        operator=(unique_ptr<_Yp, _Dp> __r);
 #endif
 
     void swap(shared_ptr& __r) _NOEXCEPT;
     void reset() _NOEXCEPT;
-    template<class _Yp> void reset(_Yp* __p);
-    template<class _Yp, class _Dp> void reset(_Yp* __p, _Dp __d);
-    template<class _Yp, class _Dp, class _Alloc> void reset(_Yp* __p, _Dp __d, _Alloc __a);
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            void
+        >::type
+        reset(_Yp* __p);
+    template<class _Yp, class _Dp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            void
+        >::type
+        reset(_Yp* __p, _Dp __d);
+    template<class _Yp, class _Dp, class _Alloc>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            void
+        >::type
+        reset(_Yp* __p, _Dp __d, _Alloc __a);
 
     _LIBCPP_INLINE_VISIBILITY
     element_type* get() const _NOEXCEPT {return __ptr_;}
@@ -3664,7 +3854,7 @@
 }
 
 template<class _Tp>
-template<class _Yp>
+template<class _Yp, class>
 shared_ptr<_Tp>::shared_ptr(_Yp* __p)
     : __ptr_(__p)
 {
@@ -3676,7 +3866,7 @@
 }
 
 template<class _Tp>
-template<class _Yp, class _Dp>
+template<class _Yp, class _Dp, class>
 shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d)
     : __ptr_(__p)
 {
@@ -3719,7 +3909,7 @@
 }
 
 template<class _Tp>
-template<class _Yp, class _Dp, class _Alloc>
+template<class _Yp, class _Dp, class _Alloc, class>
 shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a)
     : __ptr_(__p)
 {
@@ -3833,7 +4023,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template<class _Tp>
-template<class _Yp>
+template<class _Yp, class>
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r)
 #else
@@ -3848,7 +4038,7 @@
 }
 
 template<class _Tp>
-template <class _Yp, class _Dp>
+template <class _Yp, class _Dp, class>
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
 #else
@@ -3864,7 +4054,7 @@
 }
 
 template<class _Tp>
-template <class _Yp, class _Dp>
+template <class _Yp, class _Dp, class>
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
 #else
@@ -4085,7 +4275,11 @@
 template<class _Tp>
 template<class _Yp>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>&
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
 shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
 {
     shared_ptr(__r).swap(*this);
@@ -4106,7 +4300,11 @@
 template<class _Tp>
 template<class _Yp>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>&
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
 shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
 {
     shared_ptr(_VSTD::move(__r)).swap(*this);
@@ -4116,7 +4314,12 @@
 template<class _Tp>
 template<class _Yp>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>&
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<_Yp*, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
 shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
 {
     shared_ptr(_VSTD::move(__r)).swap(*this);
@@ -4126,7 +4329,12 @@
 template<class _Tp>
 template <class _Yp, class _Dp>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>&
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
 shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
 {
     shared_ptr(_VSTD::move(__r)).swap(*this);
@@ -4138,7 +4346,12 @@
 template<class _Tp>
 template<class _Yp>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>&
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<_Yp*, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
 shared_ptr<_Tp>::operator=(auto_ptr<_Yp> __r)
 {
     shared_ptr(__r).swap(*this);
@@ -4148,7 +4361,12 @@
 template<class _Tp>
 template <class _Yp, class _Dp>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>&
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
 shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp> __r)
 {
     shared_ptr(_VSTD::move(__r)).swap(*this);
@@ -4177,7 +4395,11 @@
 template<class _Tp>
 template<class _Yp>
 inline _LIBCPP_INLINE_VISIBILITY
-void
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    void
+>::type
 shared_ptr<_Tp>::reset(_Yp* __p)
 {
     shared_ptr(__p).swap(*this);
@@ -4186,7 +4408,11 @@
 template<class _Tp>
 template<class _Yp, class _Dp>
 inline _LIBCPP_INLINE_VISIBILITY
-void
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    void
+>::type
 shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
 {
     shared_ptr(__p, __d).swap(*this);
@@ -4195,7 +4421,11 @@
 template<class _Tp>
 template<class _Yp, class _Dp, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
-void
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    void
+>::type
 shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
 {
     shared_ptr(__p, __d, __a).swap(*this);
@@ -4205,7 +4435,11 @@
 
 template<class _Tp, class ..._Args>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>
+typename enable_if
+<
+    !is_array<_Tp>::value,
+    shared_ptr<_Tp>
+>::type
 make_shared(_Args&& ...__args)
 {
     return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
@@ -4213,7 +4447,11 @@
 
 template<class _Tp, class _Alloc, class ..._Args>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>
+typename enable_if
+<
+    !is_array<_Tp>::value,
+    shared_ptr<_Tp>
+>::type
 allocate_shared(const _Alloc& __a, _Args&& ...__args)
 {
     return shared_ptr<_Tp>::allocate_shared(__a, _VSTD::forward<_Args>(__args)...);
@@ -4321,7 +4559,11 @@
 
 template<class _Tp, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>
+typename enable_if
+<
+    !is_array<_Tp>::value && !is_array<_Up>::value,
+    shared_ptr<_Tp>
+>::type
 static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
 {
     return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
@@ -4329,7 +4571,11 @@
 
 template<class _Tp, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY
-shared_ptr<_Tp>
+typename enable_if
+<
+    !is_array<_Tp>::value && !is_array<_Up>::value,
+    shared_ptr<_Tp>
+>::type
 dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
 {
     _Tp* __p = dynamic_cast<_Tp*>(__r.get());
@@ -4337,10 +4583,15 @@
 }
 
 template<class _Tp, class _Up>
-shared_ptr<_Tp>
+typename enable_if
+<
+    is_array<_Tp>::value == is_array<_Up>::value,
+    shared_ptr<_Tp>
+>::type
 const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
 {
-    return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get()));
+    typedef typename remove_extent<_Tp>::type _RTp;
+    return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
 }
 
 #ifndef _LIBCPP_NO_RTTI
@@ -4374,11 +4625,43 @@
                    typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
                          _NOEXCEPT;
 
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    weak_ptr(weak_ptr&& __r) _NOEXCEPT;
+    template<class _Yp> weak_ptr(weak_ptr<_Yp>&& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                         _NOEXCEPT;
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     ~weak_ptr();
 
     weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
-    template<class _Yp> weak_ptr& operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
-    template<class _Yp> weak_ptr& operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            weak_ptr&
+        >::type
+        operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            weak_ptr&
+        >::type
+        operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            weak_ptr&
+        >::type
+        operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
 
     void swap(weak_ptr& __r) _NOEXCEPT;
     void reset() _NOEXCEPT;
@@ -4447,6 +4730,33 @@
         __cntrl_->__add_weak();
 }
 
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = 0;
+    __r.__cntrl_ = 0;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
+                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = 0;
+    __r.__cntrl_ = 0;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
 template<class _Tp>
 weak_ptr<_Tp>::~weak_ptr()
 {
@@ -4466,17 +4776,52 @@
 template<class _Tp>
 template<class _Yp>
 inline _LIBCPP_INLINE_VISIBILITY
-weak_ptr<_Tp>&
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
 weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
 {
     weak_ptr(__r).swap(*this);
     return *this;
 }
 
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
 template<class _Tp>
-template<class _Yp>
 inline _LIBCPP_INLINE_VISIBILITY
 weak_ptr<_Tp>&
+weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
+{
+    weak_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
+weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
+{
+    weak_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
 weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
 {
     weak_ptr(__r).swap(*this);





More information about the cfe-commits mailing list