Commit 302b6996 by Jonathan Wakely Committed by Jonathan Wakely

Improve API docs for <memory> and <new>

	* include/bits/shared_ptr.h: Improve docs.
	* include/bits/shared_ptr_base.h: Likewise.
	* include/bits/stl_uninitialized.h: Likewise.
	* include/bits/unique_ptr.h: Likewise.
	* libsupc++/new: Likewise.

From-SVN: r271077
parent 15e5858f
2019-05-10 Jonathan Wakely <jwakely@redhat.com>
* include/bits/shared_ptr.h: Improve docs.
* include/bits/shared_ptr_base.h: Likewise.
* include/bits/stl_uninitialized.h: Likewise.
* include/bits/unique_ptr.h: Likewise.
* libsupc++/new: Likewise.
2019-05-09 François Dumont <fdumont@gcc.gnu.org> 2019-05-09 François Dumont <fdumont@gcc.gnu.org>
* include/bits/stl_deque.h * include/bits/stl_deque.h
......
...@@ -60,7 +60,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -60,7 +60,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @{ * @{
*/ */
/// 20.7.2.2.11 shared_ptr I/O // 20.7.2.2.11 shared_ptr I/O
/// Write the stored pointer to an ostream.
/// @relates shared_ptr
template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
inline std::basic_ostream<_Ch, _Tr>& inline std::basic_ostream<_Ch, _Tr>&
operator<<(std::basic_ostream<_Ch, _Tr>& __os, operator<<(std::basic_ostream<_Ch, _Tr>& __os,
...@@ -82,6 +85,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -82,6 +85,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
/// 20.7.2.2.10 shared_ptr get_deleter /// 20.7.2.2.10 shared_ptr get_deleter
/// If `__p` has a deleter of type `_Del`, return a pointer to it.
/// @relates shared_ptr /// @relates shared_ptr
template<typename _Del, typename _Tp> template<typename _Del, typename _Tp>
inline _Del* inline _Del*
...@@ -106,6 +111,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -106,6 +111,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* A `shared_ptr` also stores another pointer, which is usually * A `shared_ptr` also stores another pointer, which is usually
* (but not always) the same pointer as it owns. The stored pointer * (but not always) the same pointer as it owns. The stored pointer
* can be retrieved by calling the `get()` member function. * can be retrieved by calling the `get()` member function.
*
* The equality and relational operators for `shared_ptr` only compare
* the stored pointer returned by `get()`, not the owned pointer.
* To test whether two `shared_ptr` objects share ownership of the same
* pointer see `std::shared_ptr::owner_before` and `std::owner_less`.
*/ */
template<typename _Tp> template<typename _Tp>
class shared_ptr : public __shared_ptr<_Tp> class shared_ptr : public __shared_ptr<_Tp>
...@@ -122,10 +132,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -122,10 +132,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public: public:
/// The type pointed to by the stored pointer, remove_extent_t<_Tp>
using element_type = typename __shared_ptr<_Tp>::element_type; using element_type = typename __shared_ptr<_Tp>::element_type;
#if __cplusplus > 201402L #if __cplusplus >= 201703L
# define __cpp_lib_shared_ptr_weak_type 201606 # define __cpp_lib_shared_ptr_weak_type 201606
/// The corresponding weak_ptr type for this shared_ptr
using weak_type = weak_ptr<_Tp>; using weak_type = weak_ptr<_Tp>;
#endif #endif
/** /**
...@@ -134,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -134,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/ */
constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { } constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
shared_ptr(const shared_ptr&) noexcept = default; shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor
/** /**
* @brief Construct a %shared_ptr that owns the pointer @a __p. * @brief Construct a %shared_ptr that owns the pointer @a __p.
...@@ -378,8 +390,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -378,8 +390,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
friend class weak_ptr<_Tp>; friend class weak_ptr<_Tp>;
}; };
/// @relates shared_ptr @{
#if __cpp_deduction_guides >= 201606 #if __cpp_deduction_guides >= 201606
template<typename _Tp> template<typename _Tp>
shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
...@@ -388,36 +398,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -388,36 +398,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif #endif
// 20.7.2.2.7 shared_ptr comparisons // 20.7.2.2.7 shared_ptr comparisons
/// @relates shared_ptr @{
/// Equality operator for shared_ptr objects, compares the stored pointers
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return __a.get() == __b.get(); } { return __a.get() == __b.get(); }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return !__a; } { return !__a; }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !__a; } { return !__a; }
/// Inequality operator for shared_ptr objects, compares the stored pointers
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return __a.get() != __b.get(); } { return __a.get() != __b.get(); }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return (bool)__a; } { return (bool)__a; }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return (bool)__a; } { return (bool)__a; }
/// Relational operator for shared_ptr objects, compares the stored pointers
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
...@@ -428,6 +448,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -428,6 +448,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return less<_Vp>()(__a.get(), __b.get()); return less<_Vp>()(__a.get(), __b.get());
} }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
...@@ -436,6 +457,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -436,6 +457,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return less<_Tp_elt*>()(__a.get(), nullptr); return less<_Tp_elt*>()(__a.get(), nullptr);
} }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
...@@ -444,52 +466,62 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -444,52 +466,62 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return less<_Tp_elt*>()(nullptr, __a.get()); return less<_Tp_elt*>()(nullptr, __a.get());
} }
/// Relational operator for shared_ptr objects, compares the stored pointers
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return !(__b < __a); } { return !(__b < __a); }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return !(nullptr < __a); } { return !(nullptr < __a); }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !(__a < nullptr); } { return !(__a < nullptr); }
/// Relational operator for shared_ptr objects, compares the stored pointers
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return (__b < __a); } { return (__b < __a); }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return nullptr < __a; } { return nullptr < __a; }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return __a < nullptr; } { return __a < nullptr; }
/// Relational operator for shared_ptr objects, compares the stored pointers
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return !(__a < __b); } { return !(__a < __b); }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return !(__a < nullptr); } { return !(__a < nullptr); }
/// shared_ptr comparison with nullptr
template<typename _Tp> template<typename _Tp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !(nullptr < __a); } { return !(nullptr < __a); }
// 20.7.2.2.8 shared_ptr specialized algorithms. // 20.7.2.2.8 shared_ptr specialized algorithms.
/// Swap overload for shared_ptr /// Swap overload for shared_ptr
template<typename _Tp> template<typename _Tp>
inline void inline void
...@@ -497,6 +529,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -497,6 +529,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ __a.swap(__b); } { __a.swap(__b); }
// 20.7.2.2.9 shared_ptr casts. // 20.7.2.2.9 shared_ptr casts.
/// Convert type of `shared_ptr`, via `static_cast` /// Convert type of `shared_ptr`, via `static_cast`
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
inline shared_ptr<_Tp> inline shared_ptr<_Tp>
...@@ -540,9 +573,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -540,9 +573,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// @} // @}
/** /**
* @brief A smart pointer with weak semantics. * @brief A non-owning observer for a pointer owned by a shared_ptr
*
* A weak_ptr provides a safe alternative to a raw pointer when you want
* a non-owning reference to an object that is managed by a shared_ptr.
* *
* With forwarding constructors and assignment operators. * Unlike a raw pointer, a weak_ptr can be converted to a new shared_ptr
* that shares ownership with every other shared_ptr that already owns
* the pointer. In other words you can upgrade from a non-owning "weak"
* reference to an owning shared_ptr, without having access to any of
* the existing shared_ptr objects.
*
* Also unlike a raw pointer, a weak_ptr does not become "dangling" after
* the object it points to has been destroyed. Instead, a weak_ptr
* becomes _expired_ and can no longer be converted to a shared_ptr that
* owns the freed pointer, so you cannot accidentally access the pointed-to
* object after it has been destroyed.
*/ */
template<typename _Tp> template<typename _Tp>
class weak_ptr : public __weak_ptr<_Tp> class weak_ptr : public __weak_ptr<_Tp>
...@@ -630,20 +676,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -630,20 +676,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp = void> template<typename _Tp = void>
struct owner_less; struct owner_less;
/// Void specialization of owner_less /// Void specialization of owner_less compares either shared_ptr or weak_ptr
template<> template<>
struct owner_less<void> : _Sp_owner_less<void, void> struct owner_less<void> : _Sp_owner_less<void, void>
{ }; { };
/// Partial specialization of owner_less for shared_ptr. /// Partial specialization of owner_less for shared_ptr.
/// @relates shared_ptr
template<typename _Tp> template<typename _Tp>
struct owner_less<shared_ptr<_Tp>> struct owner_less<shared_ptr<_Tp>>
: public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
{ }; { };
/// Partial specialization of owner_less for weak_ptr. /// Partial specialization of owner_less for weak_ptr.
/// @relates weak_ptr
template<typename _Tp> template<typename _Tp>
struct owner_less<weak_ptr<_Tp>> struct owner_less<weak_ptr<_Tp>>
: public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
...@@ -704,7 +748,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -704,7 +748,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
mutable weak_ptr<_Tp> _M_weak_this; mutable weak_ptr<_Tp> _M_weak_this;
}; };
/// @relates unique_ptr @{ /// @relates shared_ptr @{
/** /**
* @brief Create an object that is owned by a shared_ptr. * @brief Create an object that is owned by a shared_ptr.
......
...@@ -1305,21 +1305,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1305,21 +1305,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reset(_Yp* __p, _Deleter __d, _Alloc __a) reset(_Yp* __p, _Deleter __d, _Alloc __a)
{ __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); } { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); }
/// Return the stored pointer.
element_type* element_type*
get() const noexcept get() const noexcept
{ return _M_ptr; } { return _M_ptr; }
/// Return true if the stored pointer is not null.
explicit operator bool() const // never throws explicit operator bool() const // never throws
{ return _M_ptr == 0 ? false : true; } { return _M_ptr == 0 ? false : true; }
/// Return true if use_count() == 1.
bool bool
unique() const noexcept unique() const noexcept
{ return _M_refcount._M_unique(); } { return _M_refcount._M_unique(); }
/// If *this owns a pointer, return the number of owners, otherwise zero.
long long
use_count() const noexcept use_count() const noexcept
{ return _M_refcount._M_get_use_count(); } { return _M_refcount._M_get_use_count(); }
/// Exchange both the owned pointer and the stored pointer.
void void
swap(__shared_ptr<_Tp, _Lp>& __other) noexcept swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
{ {
...@@ -1327,6 +1332,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1327,6 +1332,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_refcount._M_swap(__other._M_refcount); _M_refcount._M_swap(__other._M_refcount);
} }
/** @brief Define an ordering based on ownership.
*
* This function defines a strict weak ordering between two shared_ptr
* or weak_ptr objects, such that one object is less than the other
* unless they share ownership of the same pointer, or are both empty.
* @{
*/
template<typename _Tp1> template<typename _Tp1>
bool bool
owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
...@@ -1336,6 +1348,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1336,6 +1348,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool bool
owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
{ return _M_refcount._M_less(__rhs._M_refcount); } { return _M_refcount._M_less(__rhs._M_refcount); }
// @}
protected: protected:
// This constructor is non-standard, it is used by allocate_shared. // This constructor is non-standard, it is used by allocate_shared.
......
...@@ -68,6 +68,12 @@ namespace std _GLIBCXX_VISIBILITY(default) ...@@ -68,6 +68,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
{ {
_GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @addtogroup memory
* @{
*/
/// @cond undocumented
template<bool _TrivialValueTypes> template<bool _TrivialValueTypes>
struct __uninitialized_copy struct __uninitialized_copy
{ {
...@@ -101,6 +107,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -101,6 +107,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return std::copy(__first, __last, __result); } { return std::copy(__first, __last, __result); }
}; };
/// @endcond
/** /**
* @brief Copies the range [first,last) into result. * @brief Copies the range [first,last) into result.
* @param __first An input iterator. * @param __first An input iterator.
...@@ -134,6 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -134,6 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__uninit_copy(__first, __last, __result); __uninit_copy(__first, __last, __result);
} }
/// @cond undocumented
template<bool _TrivialValueType> template<bool _TrivialValueType>
struct __uninitialized_fill struct __uninitialized_fill
...@@ -167,6 +176,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -167,6 +176,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ std::fill(__first, __last, __x); } { std::fill(__first, __last, __x); }
}; };
/// @endcond
/** /**
* @brief Copies the value x into the range [first,last). * @brief Copies the value x into the range [first,last).
* @param __first An input iterator. * @param __first An input iterator.
...@@ -194,6 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -194,6 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__uninit_fill(__first, __last, __x); __uninit_fill(__first, __last, __x);
} }
/// @cond undocumented
template<bool _TrivialValueType> template<bool _TrivialValueType>
struct __uninitialized_fill_n struct __uninitialized_fill_n
...@@ -228,6 +240,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -228,6 +240,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return std::fill_n(__first, __n, __x); } { return std::fill_n(__first, __n, __x); }
}; };
/// @endcond
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 1339. uninitialized_fill_n should return the end of its range // DR 1339. uninitialized_fill_n should return the end of its range
/** /**
...@@ -255,6 +269,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -255,6 +269,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__uninit_fill_n(__first, __n, __x); __uninit_fill_n(__first, __n, __x);
} }
/// @cond undocumented
// Extensions: versions of uninitialized_copy, uninitialized_fill, // Extensions: versions of uninitialized_copy, uninitialized_fill,
// and uninitialized_fill_n that take an allocator parameter. // and uninitialized_fill_n that take an allocator parameter.
// We dispatch back to the standard versions when we're given the // We dispatch back to the standard versions when we're given the
...@@ -474,7 +490,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -474,7 +490,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
} }
/// @endcond
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
/// @cond undocumented
// Extensions: __uninitialized_default, __uninitialized_default_n, // Extensions: __uninitialized_default, __uninitialized_default_n,
// __uninitialized_default_a, __uninitialized_default_n_a. // __uninitialized_default_a, __uninitialized_default_n_a.
...@@ -798,6 +818,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -798,6 +818,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return {__first_res, __second_res}; return {__first_res, __second_res};
} }
/// @endcond
/** /**
* @brief Copies the range [first,first+n) into result. * @brief Copies the range [first,first+n) into result.
* @param __first An input iterator. * @param __first An input iterator.
...@@ -814,6 +836,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -814,6 +836,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return std::__uninitialized_copy_n(__first, __n, __result, { return std::__uninitialized_copy_n(__first, __n, __result,
std::__iterator_category(__first)); } std::__iterator_category(__first)); }
/// @cond undocumented
template<typename _InputIterator, typename _Size, typename _ForwardIterator> template<typename _InputIterator, typename _Size, typename _ForwardIterator>
inline pair<_InputIterator, _ForwardIterator> inline pair<_InputIterator, _ForwardIterator>
__uninitialized_copy_n_pair(_InputIterator __first, _Size __n, __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
...@@ -823,12 +846,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -823,12 +846,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::__uninitialized_copy_n_pair(__first, __n, __result, std::__uninitialized_copy_n_pair(__first, __n, __result,
std::__iterator_category(__first)); std::__iterator_category(__first));
} }
/// @endcond
#endif #endif
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
# define __cpp_lib_raw_memory_algorithms 201606L # define __cpp_lib_raw_memory_algorithms 201606L
/**
* @brief Default-initializes objects in the range [first,last).
* @param __first A forward iterator.
* @param __last A forward iterator.
*/
template <typename _ForwardIterator> template <typename _ForwardIterator>
inline void inline void
uninitialized_default_construct(_ForwardIterator __first, uninitialized_default_construct(_ForwardIterator __first,
...@@ -837,6 +865,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -837,6 +865,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__uninitialized_default_novalue(__first, __last); __uninitialized_default_novalue(__first, __last);
} }
/**
* @brief Default-initializes objects in the range [first,first+count).
* @param __first A forward iterator.
* @param __count The number of objects to construct.
* @return __first + __count
*/
template <typename _ForwardIterator, typename _Size> template <typename _ForwardIterator, typename _Size>
inline _ForwardIterator inline _ForwardIterator
uninitialized_default_construct_n(_ForwardIterator __first, _Size __count) uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
...@@ -844,6 +878,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -844,6 +878,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __uninitialized_default_novalue_n(__first, __count); return __uninitialized_default_novalue_n(__first, __count);
} }
/**
* @brief Value-initializes objects in the range [first,last).
* @param __first A forward iterator.
* @param __last A forward iterator.
*/
template <typename _ForwardIterator> template <typename _ForwardIterator>
inline void inline void
uninitialized_value_construct(_ForwardIterator __first, uninitialized_value_construct(_ForwardIterator __first,
...@@ -852,6 +891,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -852,6 +891,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __uninitialized_default(__first, __last); return __uninitialized_default(__first, __last);
} }
/**
* @brief Value-initializes objects in the range [first,first+count).
* @param __first A forward iterator.
* @param __count The number of objects to construct.
* @return __result + __count
*/
template <typename _ForwardIterator, typename _Size> template <typename _ForwardIterator, typename _Size>
inline _ForwardIterator inline _ForwardIterator
uninitialized_value_construct_n(_ForwardIterator __first, _Size __count) uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
...@@ -859,6 +904,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -859,6 +904,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __uninitialized_default_n(__first, __count); return __uninitialized_default_n(__first, __count);
} }
/**
* @brief Move-construct from the range [first,last) into result.
* @param __first An input iterator.
* @param __last An input iterator.
* @param __result An output iterator.
* @return __result + (__first - __last)
*/
template <typename _InputIterator, typename _ForwardIterator> template <typename _InputIterator, typename _ForwardIterator>
inline _ForwardIterator inline _ForwardIterator
uninitialized_move(_InputIterator __first, _InputIterator __last, uninitialized_move(_InputIterator __first, _InputIterator __last,
...@@ -869,6 +921,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -869,6 +921,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result); _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
} }
/**
* @brief Move-construct from the range [first,first+count) into result.
* @param __first An input iterator.
* @param __count The number of objects to initialize.
* @param __result An output iterator.
* @return __result + __count
*/
template <typename _InputIterator, typename _Size, typename _ForwardIterator> template <typename _InputIterator, typename _Size, typename _ForwardIterator>
inline pair<_InputIterator, _ForwardIterator> inline pair<_InputIterator, _ForwardIterator>
uninitialized_move_n(_InputIterator __first, _Size __count, uninitialized_move_n(_InputIterator __first, _Size __count,
...@@ -882,6 +941,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -882,6 +941,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif // C++17 #endif // C++17
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
/// @cond undocumented
template<typename _Tp, typename _Up, typename _Allocator> template<typename _Tp, typename _Up, typename _Allocator>
inline void inline void
__relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig, __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
...@@ -948,8 +1009,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -948,8 +1009,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::__niter_base(__last), std::__niter_base(__last),
std::__niter_base(__result), __alloc); std::__niter_base(__result), __alloc);
} }
/// @endcond
#endif #endif
// @} group memory
_GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION
} // namespace } // namespace
......
...@@ -54,7 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -54,7 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
/// Primary template of default_delete, used by unique_ptr /// Primary template of default_delete, used by unique_ptr for single objects
template<typename _Tp> template<typename _Tp>
struct default_delete struct default_delete
{ {
...@@ -63,14 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -63,14 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @brief Converting constructor. /** @brief Converting constructor.
* *
* Allows conversion from a deleter for arrays of another type, @p _Up, * Allows conversion from a deleter for objects of another type, `_Up`,
* only if @p _Up* is convertible to @p _Tp*. * only if `_Up*` is convertible to `_Tp*`.
*/ */
template<typename _Up, typename = typename template<typename _Up, typename = typename
enable_if<is_convertible<_Up*, _Tp*>::value>::type> enable_if<is_convertible<_Up*, _Tp*>::value>::type>
default_delete(const default_delete<_Up>&) noexcept { } default_delete(const default_delete<_Up>&) noexcept { }
/// Calls @c delete @p __ptr /// Calls `delete __ptr`
void void
operator()(_Tp* __ptr) const operator()(_Tp* __ptr) const
{ {
...@@ -84,7 +84,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -84,7 +84,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 740 - omit specialization for array objects with a compile time length // DR 740 - omit specialization for array objects with a compile time length
/// Specialization for arrays, default_delete.
/// Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
template<typename _Tp> template<typename _Tp>
struct default_delete<_Tp[]> struct default_delete<_Tp[]>
{ {
...@@ -95,17 +96,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -95,17 +96,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @brief Converting constructor. /** @brief Converting constructor.
* *
* Allows conversion from a deleter for arrays of another type, such as * Allows conversion from a deleter for arrays of another type, such as
* a const-qualified version of @p _Tp. * a const-qualified version of `_Tp`.
* *
* Conversions from types derived from @c _Tp are not allowed because * Conversions from types derived from `_Tp` are not allowed because
* it is unsafe to @c delete[] an array of derived types through a * it is undefined to `delete[]` an array of derived types through a
* pointer to the base type. * pointer to the base type.
*/ */
template<typename _Up, typename = typename template<typename _Up, typename = typename
enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type> enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
default_delete(const default_delete<_Up[]>&) noexcept { } default_delete(const default_delete<_Up[]>&) noexcept { }
/// Calls @c delete[] @p __ptr /// Calls `delete[] __ptr`
template<typename _Up> template<typename _Up>
typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
operator()(_Up* __ptr) const operator()(_Up* __ptr) const
...@@ -116,6 +117,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -116,6 +117,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
}; };
/// @cond undocumented
template <typename _Tp, typename _Dp> template <typename _Tp, typename _Dp>
class __uniq_ptr_impl class __uniq_ptr_impl
{ {
...@@ -158,6 +161,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -158,6 +161,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private: private:
tuple<pointer, _Dp> _M_t; tuple<pointer, _Dp> _M_t;
}; };
/// @endcond
/// 20.7.1.2 unique_ptr for single objects. /// 20.7.1.2 unique_ptr for single objects.
template <typename _Tp, typename _Dp = default_delete<_Tp>> template <typename _Tp, typename _Dp = default_delete<_Tp>>
...@@ -688,6 +692,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -688,6 +692,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @relates unique_ptr @{ /// @relates unique_ptr @{
/// Swap overload for unique_ptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
inline inline
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
...@@ -707,6 +712,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -707,6 +712,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
unique_ptr<_Tp, _Dp>&) = delete; unique_ptr<_Tp, _Dp>&) = delete;
#endif #endif
/// Equality operator for unique_ptr objects, compares the owned pointers.
template<typename _Tp, typename _Dp, template<typename _Tp, typename _Dp,
typename _Up, typename _Ep> typename _Up, typename _Ep>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
...@@ -714,16 +720,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -714,16 +720,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const unique_ptr<_Up, _Ep>& __y) const unique_ptr<_Up, _Ep>& __y)
{ return __x.get() == __y.get(); } { return __x.get() == __y.get(); }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
{ return !__x; } { return !__x; }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
{ return !__x; } { return !__x; }
/// Inequality operator for unique_ptr objects, compares the owned pointers
template<typename _Tp, typename _Dp, template<typename _Tp, typename _Dp,
typename _Up, typename _Ep> typename _Up, typename _Ep>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
...@@ -731,16 +740,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -731,16 +740,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const unique_ptr<_Up, _Ep>& __y) const unique_ptr<_Up, _Ep>& __y)
{ return __x.get() != __y.get(); } { return __x.get() != __y.get(); }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
{ return (bool)__x; } { return (bool)__x; }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
{ return (bool)__x; } { return (bool)__x; }
/// Relational operator for unique_ptr objects, compares the owned pointers
template<typename _Tp, typename _Dp, template<typename _Tp, typename _Dp,
typename _Up, typename _Ep> typename _Up, typename _Ep>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
...@@ -753,6 +765,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -753,6 +765,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return std::less<_CT>()(__x.get(), __y.get()); return std::less<_CT>()(__x.get(), __y.get());
} }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
...@@ -761,6 +774,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -761,6 +774,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
nullptr); nullptr);
} }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
...@@ -769,6 +783,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -769,6 +783,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__x.get()); __x.get());
} }
/// Relational operator for unique_ptr objects, compares the owned pointers
template<typename _Tp, typename _Dp, template<typename _Tp, typename _Dp,
typename _Up, typename _Ep> typename _Up, typename _Ep>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
...@@ -776,16 +791,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -776,16 +791,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const unique_ptr<_Up, _Ep>& __y) const unique_ptr<_Up, _Ep>& __y)
{ return !(__y < __x); } { return !(__y < __x); }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
{ return !(nullptr < __x); } { return !(nullptr < __x); }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
{ return !(__x < nullptr); } { return !(__x < nullptr); }
/// Relational operator for unique_ptr objects, compares the owned pointers
template<typename _Tp, typename _Dp, template<typename _Tp, typename _Dp,
typename _Up, typename _Ep> typename _Up, typename _Ep>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
...@@ -793,6 +811,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -793,6 +811,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const unique_ptr<_Up, _Ep>& __y) const unique_ptr<_Up, _Ep>& __y)
{ return (__y < __x); } { return (__y < __x); }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
...@@ -801,6 +820,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -801,6 +820,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__x.get()); __x.get());
} }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
...@@ -809,6 +829,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -809,6 +829,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
nullptr); nullptr);
} }
/// Relational operator for unique_ptr objects, compares the owned pointers
template<typename _Tp, typename _Dp, template<typename _Tp, typename _Dp,
typename _Up, typename _Ep> typename _Up, typename _Ep>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
...@@ -816,11 +837,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -816,11 +837,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const unique_ptr<_Up, _Ep>& __y) const unique_ptr<_Up, _Ep>& __y)
{ return !(__x < __y); } { return !(__x < __y); }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
{ return !(__x < nullptr); } { return !(__x < nullptr); }
/// unique_ptr comparison with nullptr
template<typename _Tp, typename _Dp> template<typename _Tp, typename _Dp>
_GLIBCXX_NODISCARD inline bool _GLIBCXX_NODISCARD inline bool
operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
* *
* The header @c new defines several functions to manage dynamic memory and * The header @c new defines several functions to manage dynamic memory and
* handling memory allocation errors; see * handling memory allocation errors; see
* http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#4 for more. * https://gcc.gnu.org/onlinedocs/libstdc++/manual/dynamic_memory.html
* for more.
*/ */
#ifndef _NEW #ifndef _NEW
...@@ -211,10 +212,13 @@ namespace std ...@@ -211,10 +212,13 @@ namespace std
#if __cplusplus > 201703L #if __cplusplus > 201703L
namespace std namespace std
{ {
/// Tag type used to declare a class-specific operator delete that can
/// invoke the destructor before deallocating the memory.
struct destroying_delete_t struct destroying_delete_t
{ {
explicit destroying_delete_t() = default; explicit destroying_delete_t() = default;
}; };
/// Tag variable of type destroying_delete_t.
inline constexpr destroying_delete_t destroying_delete{}; inline constexpr destroying_delete_t destroying_delete{};
} }
// Only define the feature test macro if the compiler supports the feature: // Only define the feature test macro if the compiler supports the feature:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment