From: Jonathan Wakely Date: Sat, 18 May 2013 20:18:55 +0000 (+0000) Subject: unique_ptr.h (make_unique): Declare inline. X-Git-Tag: releases/gcc-4.9.0~5818 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=05a4261b10b4649e88f19cc23c5a7badb71fc401;p=thirdparty%2Fgcc.git unique_ptr.h (make_unique): Declare inline. * include/bits/unique_ptr.h (make_unique): Declare inline. (unique_ptr::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 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6a89ad7d1e44..db995a767fab 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2013-05-18 Jonathan Wakely + + * include/bits/unique_ptr.h (make_unique): Declare inline. + (unique_ptr::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 + + * doc/xml/manual/status_cxx2011.xml: Fix markup error. + 2013-05-18 Jonathan Wakely * doc/xml/manual/status_cxx2011.xml: Fix markup error. diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index 71f1b692a180..3a99cff0061d 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 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 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 a0f513f5def3..fb19d0887dcb 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 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 e98b85f7da4d..c6c9a5a04a5c 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 class auto_ptr; #endif - /// Primary template, default_delete. + /// Primary template of default_delete, used by unique_ptr template 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::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 struct default_delete<_Tp[]> { @@ -85,12 +92,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __not_, __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::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::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::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::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::type&& __d) noexcept : _M_t(std::move(__p), std::move(__d)) { static_assert(!std::is_reference::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(__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::pointer, pointer>, __not_>, @@ -171,12 +220,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } #if _GLIBCXX_USE_DEPRECATED + /// Converting constructor from @c auto_ptr template, 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 enable_if< __and_< is_convertible::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::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::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::value, "constructed with null function pointer deleter"); } + // Disable construction from convertible pointer types. template, 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::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::type&& __d) noexcept : _M_t(std::move(__p), std::move(__d)) { static_assert(!is_reference::value, "rvalue deleter bound to reference"); } - // Move constructor. + /// Move constructor. unique_ptr(unique_ptr&& __u) noexcept : _M_t(__u.release(), std::forward(__u.get_deleter())) { } + /// Creates a unique_ptr that owns nothing. constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } template(__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 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::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, 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::value, deleter_type, const deleter_type&>::type) = delete; + // Disable construction from convertible pointer types. template, 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 _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 _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 _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 ffcb611ca76b..d0619fd9ca0c 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 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 a0f0ed95e750..c78564270f41 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 ub(nullptr, b); std::unique_ptr 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 uba(nullptr, b); std::unique_ptr uda(nullptr, d); uba = std::move(uda); -// { dg-error "use of deleted function" "" { target *-*-* } 396 } +// { dg-error "use of deleted function" "" { target *-*-* } 515 } }