diff options
author | Jonathan Wakely <jwakely.gcc@gmail.com> | 2013-05-18 20:18:55 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2013-05-18 21:18:55 +0100 |
commit | 05a4261b10b4649e88f19cc23c5a7badb71fc401 (patch) | |
tree | d9760becd472f3a39b3bb47bb7a52a89d8170354 /libstdc++-v3 | |
parent | 82ec8686e79aaa48f294c0a9bb5dd7338b68afde (diff) | |
download | gcc-05a4261b10b4649e88f19cc23c5a7badb71fc401.zip gcc-05a4261b10b4649e88f19cc23c5a7badb71fc401.tar.gz gcc-05a4261b10b4649e88f19cc23c5a7badb71fc401.tar.bz2 |
unique_ptr.h (make_unique): Declare inline.
* include/bits/unique_ptr.h (make_unique): Declare inline.
(unique_ptr<T[],D>::reset()): Combine two overloads into one.
(default_delete, unique_ptr): Add doxygen comments.
* include/bits/shared_ptr_base.h: Improve doxygen comments.
* include/bits/shared_ptr.h: Likewise.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust dg-error line
number.
* testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.
From-SVN: r199069
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 15 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr_base.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/unique_ptr.h | 159 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc | 4 |
6 files changed, 168 insertions, 20 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6a89ad7..db995a7 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,20 @@ 2013-05-18 Jonathan Wakely <jwakely.gcc@gmail.com> + * include/bits/unique_ptr.h (make_unique): Declare inline. + (unique_ptr<T[],D>::reset()): Combine two overloads into one. + (default_delete, unique_ptr): Add doxygen comments. + * include/bits/shared_ptr_base.h: Improve doxygen comments. + * include/bits/shared_ptr.h: Likewise. + * testsuite/20_util/default_delete/48631_neg.cc: Adjust dg-error line + number. + * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise. + +2013-05-18 Jonathan Wakely <jwakely.gcc@gmail.com> + + * doc/xml/manual/status_cxx2011.xml: Fix markup error. + +2013-05-18 Jonathan Wakely <jwakely.gcc@gmail.com> + * doc/xml/manual/status_cxx2011.xml: Fix markup error. 2013-05-18 Jonathan Wakely <jwakely.gcc@gmail.com> diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index 71f1b69..3a99cff 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -60,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ - /// 2.2.3.7 shared_ptr I/O + /// 20.7.2.2.11 shared_ptr I/O template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> inline std::basic_ostream<_Ch, _Tr>& operator<<(std::basic_ostream<_Ch, _Tr>& __os, @@ -70,7 +70,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __os; } - /// 2.2.3.10 shared_ptr get_deleter (experimental) + /// 20.7.2.2.10 shared_ptr get_deleter template<typename _Del, typename _Tp, _Lock_policy _Lp> inline _Del* get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index a0f513f..fb19d08 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1204,13 +1204,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public _Sp_less<__shared_ptr<_Tp, _Lp>> { }; - // 2.2.3.8 shared_ptr specialized algorithms. + // 20.7.2.2.8 shared_ptr specialized algorithms. template<typename _Tp, _Lock_policy _Lp> inline void swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept { __a.swap(__b); } - // 2.2.3.9 shared_ptr casts + // 20.7.2.2.9 shared_ptr casts // The seemingly equivalent code: // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index e98b85f..c6c9a5a 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -49,16 +49,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename> class auto_ptr; #endif - /// Primary template, default_delete. + /// Primary template of default_delete, used by unique_ptr template<typename _Tp> struct default_delete { + /// Default constructor constexpr default_delete() noexcept = default; + /** @brief Converting constructor. + * + * Allows conversion from a deleter for arrays of another type, @p _Up, + * only if @p _Up* is convertible to @p _Tp*. + */ template<typename _Up, typename = typename enable_if<is_convertible<_Up*, _Tp*>::value>::type> default_delete(const default_delete<_Up>&) noexcept { } + /// Calls @c delete @p __ptr void operator()(_Tp* __ptr) const { @@ -70,7 +77,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 740 - omit specialization for array objects with a compile time length - /// Specialization, default_delete. + /// Specialization for arrays, default_delete. template<typename _Tp> struct default_delete<_Tp[]> { @@ -85,12 +92,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; public: + /// Default constructor constexpr default_delete() noexcept = default; + /** @brief Converting constructor. + * + * Allows conversion from a deleter for arrays of another type, such as + * a const-qualified version of @p _Tp. + * + * Conversions from types derived from @c _Tp are not allowed because + * it is unsafe to @c delete[] an array of derived types through a + * pointer to the base type. + */ template<typename _Up, typename = typename enable_if<!__is_derived_Tp<_Up>::value>::type> default_delete(const default_delete<_Up[]>&) noexcept { } + /// Calls @c delete[] @p __ptr void operator()(_Tp* __ptr) const { @@ -132,34 +150,65 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Dp deleter_type; // Constructors. + + /// Default constructor, creates a unique_ptr that owns nothing. constexpr unique_ptr() noexcept : _M_t() { static_assert(!is_pointer<deleter_type>::value, "constructed with null function pointer deleter"); } + /** Takes ownership of a pointer. + * + * @param __p A pointer to an object of @c element_type + * + * The deleter will be value-initialized. + */ explicit unique_ptr(pointer __p) noexcept : _M_t(__p, deleter_type()) { static_assert(!is_pointer<deleter_type>::value, "constructed with null function pointer deleter"); } + /** Takes ownership of a pointer. + * + * @param __p A pointer to an object of @c element_type + * @param __d A reference to a deleter. + * + * The deleter will be initialized with @p __d + */ unique_ptr(pointer __p, typename conditional<is_reference<deleter_type>::value, deleter_type, const deleter_type&>::type __d) noexcept : _M_t(__p, __d) { } + /** Takes ownership of a pointer. + * + * @param __p A pointer to an object of @c element_type + * @param __d An rvalue reference to a deleter. + * + * The deleter will be initialized with @p std::move(__d) + */ unique_ptr(pointer __p, typename remove_reference<deleter_type>::type&& __d) noexcept : _M_t(std::move(__p), std::move(__d)) { static_assert(!std::is_reference<deleter_type>::value, "rvalue deleter bound to reference"); } + /// Creates a unique_ptr that owns nothing. constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // Move constructors. + + /// Move constructor. unique_ptr(unique_ptr&& __u) noexcept : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } + /** @brief Converting constructor from another type + * + * Requires that the pointer owned by @p __u is convertible to the + * type of pointer owned by this object, @p __u does not own an array, + * and @p __u has a compatible deleter type. + */ template<typename _Up, typename _Ep, typename = _Require< is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, __not_<is_array<_Up>>, @@ -171,12 +220,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } #if _GLIBCXX_USE_DEPRECATED + /// Converting constructor from @c auto_ptr template<typename _Up, typename = _Require< is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> unique_ptr(auto_ptr<_Up>&& __u) noexcept; #endif - // Destructor. + /// Destructor, invokes the deleter if the stored pointer is not null. ~unique_ptr() noexcept { auto& __ptr = std::get<0>(_M_t); @@ -186,6 +236,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // Assignment. + + /** @brief Move assignment operator. + * + * @param __u The object to transfer ownership from. + * + * Invokes the deleter first if this object owns a pointer. + */ unique_ptr& operator=(unique_ptr&& __u) noexcept { @@ -194,6 +251,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + /** @brief Assignment from another type. + * + * @param __u The object to transfer ownership from, which owns a + * convertible pointer to a non-array object. + * + * Invokes the deleter first if this object owns a pointer. + */ template<typename _Up, typename _Ep> typename enable_if< __and_< is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, @@ -207,6 +271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + /// Reset the %unique_ptr to empty, invoking the deleter if necessary. unique_ptr& operator=(nullptr_t) noexcept { @@ -215,6 +280,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // Observers. + + /// Dereference the stored pointer. typename add_lvalue_reference<element_type>::type operator*() const { @@ -222,6 +289,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *get(); } + /// Return the stored pointer. pointer operator->() const noexcept { @@ -229,22 +297,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return get(); } + /// Return the stored pointer. pointer get() const noexcept { return std::get<0>(_M_t); } + /// Return a reference to the stored deleter. deleter_type& get_deleter() noexcept { return std::get<1>(_M_t); } + /// Return a reference to the stored deleter. const deleter_type& get_deleter() const noexcept { return std::get<1>(_M_t); } + /// Return @c true if the stored pointer is not null. explicit operator bool() const noexcept { return get() == pointer() ? false : true; } // Modifiers. + + /// Release ownership of any stored pointer. pointer release() noexcept { @@ -253,6 +327,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __p; } + /** @brief Replace the stored pointer. + * + * @param __p The new pointer to store. + * + * The deleter will be invoked if a pointer is already owned. + */ void reset(pointer __p = pointer()) noexcept { @@ -262,6 +342,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get_deleter()(__p); } + /// Exchange the pointer and deleter with another object. void swap(unique_ptr& __u) noexcept { @@ -326,37 +407,61 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Dp deleter_type; // Constructors. + + /// Default constructor, creates a unique_ptr that owns nothing. constexpr unique_ptr() noexcept : _M_t() { static_assert(!std::is_pointer<deleter_type>::value, "constructed with null function pointer deleter"); } + /** Takes ownership of a pointer. + * + * @param __p A pointer to an array of @c element_type + * + * The deleter will be value-initialized. + */ explicit unique_ptr(pointer __p) noexcept : _M_t(__p, deleter_type()) { static_assert(!is_pointer<deleter_type>::value, "constructed with null function pointer deleter"); } + // Disable construction from convertible pointer types. template<typename _Up, typename = _Require<is_pointer<pointer>, is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> explicit unique_ptr(_Up* __p) = delete; + /** Takes ownership of a pointer. + * + * @param __p A pointer to an array of @c element_type + * @param __d A reference to a deleter. + * + * The deleter will be initialized with @p __d + */ unique_ptr(pointer __p, typename conditional<is_reference<deleter_type>::value, deleter_type, const deleter_type&>::type __d) noexcept : _M_t(__p, __d) { } + /** Takes ownership of a pointer. + * + * @param __p A pointer to an array of @c element_type + * @param __d A reference to a deleter. + * + * The deleter will be initialized with @p std::move(__d) + */ unique_ptr(pointer __p, typename remove_reference<deleter_type>::type&& __d) noexcept : _M_t(std::move(__p), std::move(__d)) { static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference"); } - // Move constructor. + /// Move constructor. unique_ptr(unique_ptr&& __u) noexcept : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } + /// Creates a unique_ptr that owns nothing. constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } template<typename _Up, typename _Ep, @@ -369,7 +474,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) { } - // Destructor. + /// Destructor, invokes the deleter if the stored pointer is not null. ~unique_ptr() { auto& __ptr = std::get<0>(_M_t); @@ -379,6 +484,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // Assignment. + + /** @brief Move assignment operator. + * + * @param __u The object to transfer ownership from. + * + * Invokes the deleter first if this object owns a pointer. + */ unique_ptr& operator=(unique_ptr&& __u) noexcept { @@ -387,6 +499,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + /** @brief Assignment from another type. + * + * @param __u The object to transfer ownership from, which owns a + * convertible pointer to an array object. + * + * Invokes the deleter first if this object owns a pointer. + */ template<typename _Up, typename _Ep> typename enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type @@ -397,6 +516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + /// Reset the %unique_ptr to empty, invoking the deleter if necessary. unique_ptr& operator=(nullptr_t) noexcept { @@ -405,6 +525,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // Observers. + + /// Access an element of owned array. typename std::add_lvalue_reference<element_type>::type operator[](size_t __i) const { @@ -412,22 +534,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return get()[__i]; } + /// Return the stored pointer. pointer get() const noexcept { return std::get<0>(_M_t); } + /// Return a reference to the stored deleter. deleter_type& get_deleter() noexcept { return std::get<1>(_M_t); } + /// Return a reference to the stored deleter. const deleter_type& get_deleter() const noexcept { return std::get<1>(_M_t); } + /// Return @c true if the stored pointer is not null. explicit operator bool() const noexcept { return get() == pointer() ? false : true; } // Modifiers. + + /// Release ownership of any stored pointer. pointer release() noexcept { @@ -436,12 +564,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __p; } + /** @brief Replace the stored pointer. + * + * @param __p The new pointer to store. + * + * The deleter will be invoked if a pointer is already owned. + */ void - reset() noexcept - { reset(pointer()); } - - void - reset(pointer __p) noexcept + reset(pointer __p = pointer()) noexcept { using std::swap; swap(std::get<0>(_M_t), __p); @@ -449,10 +579,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get_deleter()(__p); } + // Disable resetting from convertible pointer types. template<typename _Up, typename = _Require<is_pointer<pointer>, is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> void reset(_Up*) = delete; + /// Exchange the pointer and deleter with another object. void swap(unique_ptr& __u) noexcept { @@ -471,6 +603,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION conditional<is_reference<deleter_type>::value, deleter_type, const deleter_type&>::type) = delete; + // Disable construction from convertible pointer types. template<typename _Up, typename = _Require<is_pointer<pointer>, is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> unique_ptr(_Up*, typename @@ -622,19 +755,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// std::make_unique for single objects template<typename _Tp, typename... _Args> - typename _MakeUniq<_Tp>::__single_object + inline typename _MakeUniq<_Tp>::__single_object make_unique(_Args&&... __args) { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } /// std::make_unique for arrays of unknown bound template<typename _Tp> - typename _MakeUniq<_Tp>::__array + inline typename _MakeUniq<_Tp>::__array make_unique(size_t __num) { return unique_ptr<_Tp>(new typename remove_extent<_Tp>::type[__num]()); } /// Disable std::make_unique for arrays of known bound template<typename _Tp, typename... _Args> - typename _MakeUniq<_Tp>::__invalid_type + inline typename _MakeUniq<_Tp>::__invalid_type make_unique(_Args&&...) = delete; #endif diff --git a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc index ffcb611..d0619fd 100644 --- a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc +++ b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc @@ -27,4 +27,4 @@ struct D : B { }; D d; std::default_delete<B[]> db; typedef decltype(db(&d)) type; // { dg-error "use of deleted function" } -// { dg-error "declared here" "" { target *-*-* } 104 } +// { dg-error "declared here" "" { target *-*-* } 122 } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc index a0f0ed9..c785642 100644 --- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc @@ -41,10 +41,10 @@ void f() std::unique_ptr<int, B&> ub(nullptr, b); std::unique_ptr<int, D&> ud(nullptr, d); ub = std::move(ud); -// { dg-error "use of deleted function" "" { target *-*-* } 206 } +// { dg-error "use of deleted function" "" { target *-*-* } 270 } std::unique_ptr<int[], B&> uba(nullptr, b); std::unique_ptr<int[], D&> uda(nullptr, d); uba = std::move(uda); -// { dg-error "use of deleted function" "" { target *-*-* } 396 } +// { dg-error "use of deleted function" "" { target *-*-* } 515 } } |