Re: [v3 PATCH] Implement 2801, Default-constructibility of unique_ptr.
On 29/12/16 22:10 +0200, Ville Voutilainen wrote: On 29 December 2016 at 21:57, Ville Voutilainenwrote: Instead of repeating this condition half a dozen times, we could put it in the __uniq_ptr_impl class template and reuse it, as in the attached patch (and similarly for the unique_ptr specialization). What do you think? It needs to be a bit more dependent than in that patch, I think. I adjusted the idea a bit, a new patch attached. It cleans up the code a bit, so it's better, but not a huge improvement. Gets a bit better by keeping the __uniq_ptr_impl as just an enable_if, aliasing its ::type locally and then using the result in the constraints. Also gets rid of a bunch of dg-errors in ptr_deleter_neg.cc. This makes me quite happy. The attached _3.diff shows the cleanup, the _4.diff shows the full patch with this cleanup applied. Looks good. OK for trunk, thanks.
Re: [v3 PATCH] Implement 2801, Default-constructibility of unique_ptr.
On 29 December 2016 at 21:57, Ville Voutilainenwrote: >> Instead of repeating this condition half a dozen times, we could put >> it in the __uniq_ptr_impl class template and reuse it, as in the >> attached patch (and similarly for the unique_ptr specialization). >> What do you think? > > It needs to be a bit more dependent than in that patch, I think. I > adjusted the idea a bit, > a new patch attached. It cleans up the code a bit, so it's better, but > not a huge improvement. Gets a bit better by keeping the __uniq_ptr_impl as just an enable_if, aliasing its ::type locally and then using the result in the constraints. Also gets rid of a bunch of dg-errors in ptr_deleter_neg.cc. This makes me quite happy. The attached _3.diff shows the cleanup, the _4.diff shows the full patch with this cleanup applied. diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index f994c59..211043f 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -158,7 +158,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { template using _DeleterConstraint = - typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint; + typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; __uniq_ptr_impl<_Tp, _Dp> _M_t; @@ -184,7 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Default constructor, creates a unique_ptr that owns nothing. template ::type> + typename = _DeleterConstraint<_Up>> constexpr unique_ptr() noexcept : _M_t() { } @@ -196,7 +196,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The deleter will be value-initialized. */ template ::type> + typename = _DeleterConstraint<_Up>> explicit unique_ptr(pointer __p) noexcept : _M_t(__p) @@ -229,7 +229,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Creates a unique_ptr that owns nothing. template ::type> + typename = _DeleterConstraint<_Up>> constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // Move constructors. @@ -398,7 +398,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { template using _DeleterConstraint = - typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint; + typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; __uniq_ptr_impl<_Tp, _Dp> _M_t; @@ -449,7 +449,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Default constructor, creates a unique_ptr that owns nothing. template ::type> + typename = _DeleterConstraint<_Up>> constexpr unique_ptr() noexcept : _M_t() { } @@ -463,7 +463,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template::type, + typename = _DeleterConstraint<_Vp>, typename = typename enable_if< __safe_conversion_raw<_Up>::value, bool>::type> explicit @@ -510,7 +510,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Creates a unique_ptr that owns nothing. template ::type> + typename = _DeleterConstraint<_Up>> constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } templatediff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index 56e6ec0..211043f 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -130,6 +130,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; public: + using _DeleterConstraint = enable_if< +__and_<__not_ >, + is_default_constructible<_Dp>>::value>; + using pointer = typename _Ptr<_Tp, _Dp>::type; __uniq_ptr_impl() = default; @@ -152,6 +156,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template > class unique_ptr { + template + using _DeleterConstraint = + typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; + __uniq_ptr_impl<_Tp, _Dp> _M_t; public: @@ -175,10 +183,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 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"); } + template > + constexpr unique_ptr() noexcept + : _M_t() +{ } /** Takes ownership of a pointer. * @@ -186,11 +195,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The deleter will be value-initialized. */ - explicit - unique_ptr(pointer __p) noexcept - : _M_t(__p) - { static_assert(!is_pointer::value, -"constructed with null function pointer deleter"); } + template > + explicit + unique_ptr(pointer __p) noexcept + : _M_t(__p) +{ } /** Takes ownership of
Re: [v3 PATCH] Implement 2801, Default-constructibility of unique_ptr.
On 22 December 2016 at 19:11, Jonathan Wakelywrote: >> /// Default constructor, creates a unique_ptr that owns nothing. >> + template > + typename enable_if< >> + __and_<__not_ >, >> +is_default_constructible<_Up>>::value, >> + bool>::type = false> > > > Instead of repeating this condition half a dozen times, we could put > it in the __uniq_ptr_impl class template and reuse it, as in the > attached patch (and similarly for the unique_ptr specialization). > What do you think? It needs to be a bit more dependent than in that patch, I think. I adjusted the idea a bit, a new patch attached. It cleans up the code a bit, so it's better, but not a huge improvement. >> constexpr unique_ptr() noexcept >> : _M_t() >> - { static_assert(!is_pointer::value, >> -"constructed with null function pointer deleter"); } >> + { } > The bodies of these constructors should be indented now that they're > templates. Hopefully fixed correctly in the new patch, please double-check. >> --- /dev/null >> +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/default.cc >> @@ -0,0 +1,40 @@ >> +// { dg-do compile { target c++11 } } >> + >> +// Copyright (C) 2011-2016 Free Software Foundation, Inc. > Is this substantially copied from an existing file, or should it just > be 2016? (Not that it really matters, as I don't think we should have Should just be 2016, fixed. 2016-12-29 Ville Voutilainen Implement 2801, Default-constructibility of unique_ptr. * include/bits/unique_ptr.h (__uniq_ptr_impl::_DeleterConstraint): New. (unique_ptr::_DeleterConstraint): Likewise. (unique_ptr()): Constrain. (unique_ptr(pointer)): Likewise. (unique_ptr(nullptr_t)): Likewise. (unique_ptr<_Tp[], _Dp>::_DeleterConstraint): New. (unique_ptr<_Tp[], _Dp>::unique_ptr()): Constrain. (unique_ptr<_Tp[], _Dp>::unique_ptr(_Up)): Likewise. (unique_ptr<_Tp[], _Dp>::unique_ptr(nullptr_t)): Likewise. * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Adjust. * testsuite/20_util/unique_ptr/cons/cv_qual_neg.cc: Likewise. * testsuite/20_util/unique_ptr/cons/default.cc: New. * testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc: Adjust. diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index 56e6ec0..f994c59 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -130,6 +130,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; public: + using _DeleterConstraint = enable_if< +__and_<__not_ >, + is_default_constructible<_Dp>>::value>; + using pointer = typename _Ptr<_Tp, _Dp>::type; __uniq_ptr_impl() = default; @@ -152,6 +156,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template > class unique_ptr { + template + using _DeleterConstraint = + typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint; + __uniq_ptr_impl<_Tp, _Dp> _M_t; public: @@ -175,10 +183,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 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"); } + template ::type> + constexpr unique_ptr() noexcept + : _M_t() +{ } /** Takes ownership of a pointer. * @@ -186,11 +195,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The deleter will be value-initialized. */ - explicit - unique_ptr(pointer __p) noexcept - : _M_t(__p) - { static_assert(!is_pointer::value, -"constructed with null function pointer deleter"); } + template ::type> + explicit + unique_ptr(pointer __p) noexcept + : _M_t(__p) +{ } /** Takes ownership of a pointer. * @@ -218,7 +228,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "rvalue deleter bound to reference"); } /// Creates a unique_ptr that owns nothing. - constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } + template ::type> + constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // Move constructors. @@ -384,6 +396,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template class unique_ptr<_Tp[], _Dp> { + template + using _DeleterConstraint = + typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint; + __uniq_ptr_impl<_Tp, _Dp> _M_t; template @@ -432,10 +448,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Constructors. /// Default constructor, creates a unique_ptr that owns nothing. - constexpr unique_ptr() noexcept - : _M_t() - {
Re: [v3 PATCH] Implement 2801, Default-constructibility of unique_ptr.
On 20/12/16 22:52 +0200, Ville Voutilainen wrote: diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index 56e6ec0..63dff37 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -175,10 +175,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Constructors. /// Default constructor, creates a unique_ptr that owns nothing. + template >, +is_default_constructible<_Up>>::value, + bool>::type = false> Instead of repeating this condition half a dozen times, we could put it in the __uniq_ptr_impl class template and reuse it, as in the attached patch (and similarly for the unique_ptrspecialization). What do you think? constexpr unique_ptr() noexcept : _M_t() - { static_assert(!is_pointer::value, -"constructed with null function pointer deleter"); } + { } The bodies of these constructors should be indented now that they're templates. --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/default.cc @@ -0,0 +1,40 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2011-2016 Free Software Foundation, Inc. Is this substantially copied from an existing file, or should it just be 2016? (Not that it really matters, as I don't think we should have copyright notices on tests like this at all, but that's something to worry about another time. diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index 56e6ec0..f9ab9a6 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -130,6 +130,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; public: + using _DeleterConstraint = enable_if< + __and_<__not_ , is_default_constructible<_Dp>>>::value>; + using pointer = typename _Ptr<_Tp, _Dp>::type; __uniq_ptr_impl() = default; @@ -152,6 +155,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template > class unique_ptr { + using _DeleterConstraint = __uniq_ptr_impl<_Tp, _Dp>::_DeleterConstraint; + __uniq_ptr_impl<_Tp, _Dp> _M_t; public: @@ -175,10 +180,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 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"); } + template + constexpr unique_ptr() noexcept + : _M_t() + { } /** Takes ownership of a pointer. * @@ -186,11 +191,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The deleter will be value-initialized. */ - explicit - unique_ptr(pointer __p) noexcept - : _M_t(__p) - { static_assert(!is_pointer::value, - "constructed with null function pointer deleter"); } + template + explicit + unique_ptr(pointer __p) noexcept + : _M_t(__p) + { } /** Takes ownership of a pointer. * @@ -218,7 +223,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "rvalue deleter bound to reference"); } /// Creates a unique_ptr that owns nothing. - constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } + template + constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // Move constructors.