Re: [v3 PATCH, RFC] Implement LWG 2729 for tuple
On 31/08/16 19:49 +0300, Ville Voutilainen wrote: @@ -338,6 +345,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; + template +struct __is_tuple_impl_trait_impl : false_type + { }; + + template +struct __is_tuple_impl_trait_impl<_Tuple_impl<_Idx, _Tp...>> : true_type + { }; + + template +struct __is_tuple_impl_trait : public __is_tuple_impl_trait_impl<_Tp> + { }; Please align the class bodies with the "struct" keyword here. Otherwise OK for trunk, thanks.
Re: [v3 PATCH, RFC] Implement LWG 2729 for tuple
On 31 August 2016 at 18:40, Ville Voutilainenwrote: > Now tested with the full testsuite on Linux-PPC64, test in the patch > amended slightly. > New patch attached. I added some more torture to the new test and re-indented it. diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index c06a040..9f43732 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -220,8 +220,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr - _Tuple_impl(_Tuple_impl&& __in) - noexcept(__and_ , + _Tuple_impl(typename conditional< + __and_ , +is_move_constructible<_Inherited>>::value, + _Tuple_impl&&, __nonesuch&&>::type __in) + noexcept(__and_ , is_nothrow_move_constructible<_Inherited>>::value) : _Inherited(std::move(_M_tail(__in))), _Base(std::forward<_Head>(_M_head(__in))) { } @@ -232,7 +235,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template -constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) +constexpr _Tuple_impl(typename conditional< + __and_ , + is_move_constructible<_Inherited>>::value, + _Tuple_impl<_Idx, _UHead, _UTails...>&&, + __nonesuch&&>::type __in) : _Inherited(std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(std::forward<_UHead> @@ -338,6 +345,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; + template +struct __is_tuple_impl_trait_impl : false_type + { }; + + template +struct __is_tuple_impl_trait_impl<_Tuple_impl<_Idx, _Tp...>> : true_type + { }; + + template +struct __is_tuple_impl_trait : public __is_tuple_impl_trait_impl<_Tp> + { }; + // Basis case of inheritance recursion. template struct _Tuple_impl<_Idx, _Head> @@ -356,11 +375,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl() : _Base() { } + template::value, + bool>::type=true> explicit constexpr _Tuple_impl(const _Head& __head) : _Base(__head) { } - template + template, +__not_<__is_tuple_impl_trait< + typename +remove_reference<_UHead>::type>> +>::value, + bool>::type = true> explicit constexpr _Tuple_impl(_UHead&& __head) : _Base(std::forward<_UHead>(__head)) { } @@ -368,15 +396,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr - _Tuple_impl(_Tuple_impl&& __in) + _Tuple_impl(typename conditional< + is_move_constructible<_Head>::value, + _Tuple_impl&&, __nonesuch&&>::type __in) noexcept(is_nothrow_move_constructible<_Head>::value) : _Base(std::forward<_Head>(_M_head(__in))) { } - template + template::value, + bool>::type = true> constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } - template + template::value, + bool>::type = true> constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } @@ -832,14 +866,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } tuple& - operator=(const tuple& __in) + operator=(typename + conditional<__and_ ...>::value, + const tuple&, const __nonesuch&>::type __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& - operator=(tuple&& __in) + operator=(typename + conditional<__and_ ...>::value, + tuple&&, __nonesuch&&>::type __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); @@ -848,7 +886,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template::type> +== sizeof...(_Elements) + && + __and_ ...>::value>::type> tuple& operator=(const tuple<_UElements...>& __in) { @@ -858,7 +899,10 @@
[v3 PATCH, RFC] Implement LWG 2729 for tuple
First, pardons all around if I'm completely repeating what Marc already tried to do. I think I'm taking a different approach. I'm not adding any defaulted or deleted functions, so I don't think I'm changing triviality. Chances are I need to actually delete the copy operations I want to get rid of, though; currently they are defined with a conditional parameter type. That leaves open the possibility of a move operation being implicitly defaulted rather than suppressed, which can make them trivial where they weren't before. I'm not sure whether this has abi impact. In the sense that this is making previously-defined move operations suppressed, maybe. I guess I could alternatively try making them conditional, and making the inverse of the conditional private; that should keep the traits working and retain abi compatibility, because I don't think our toolchains at least on non-Windows platforms include access levels in mangling. Tested for tuple on Linux-x64. Thoughts? 2016-08-30 Ville VoutilainenImplement LWG 2729 for tuple. * include/std/tuple (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally. (_Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&&)): Likewise. (__is_tuple_impl_trait_impl, __is_tuple_impl_trait): New. (_Tuple_impl(const _Head&)): Constrain. (_Tuple_impl(_UHead&&)): Likewise. (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally. (_Tuple_impl(const _Tuple_impl<_Idx, _UHead>&)): Constrain. (_Tuple_impl(_Tuple_impl<_Idx, _UHead>&&)): Likewise. (operator=(const tuple&)): Enable conditionally. (operator=(tuple&&)): Suppress conditionally. (operator=(const tuple<_UElements...>&)): Constrain. (operator=(tuple<_UElements...>&&)): Likewise. (operator=(const tuple&)): Enable conditionally (2-param tuple). (operator=(tuple&&)): Suppress conditionally (2-param tuple). (operator=(const tuple<_U1, _U2>&)): Constrain. (operator=(tuple<_U1, _U2>&&)): Likewise. (operator=(const pair<_U1, _U2>&)): Likewise. (operator=(pair<_U1, _U2>&&)): Likewise. * testsuite/20_util/tuple/element_access/get_neg.cc: Adjust. * testsuite/20_util/tuple/tuple_traits.cc: New. diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index c06a040..9f43732 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -220,8 +220,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr - _Tuple_impl(_Tuple_impl&& __in) - noexcept(__and_ , + _Tuple_impl(typename conditional< + __and_ , +is_move_constructible<_Inherited>>::value, + _Tuple_impl&&, __nonesuch&&>::type __in) + noexcept(__and_ , is_nothrow_move_constructible<_Inherited>>::value) : _Inherited(std::move(_M_tail(__in))), _Base(std::forward<_Head>(_M_head(__in))) { } @@ -232,7 +235,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template -constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) +constexpr _Tuple_impl(typename conditional< + __and_ , + is_move_constructible<_Inherited>>::value, + _Tuple_impl<_Idx, _UHead, _UTails...>&&, + __nonesuch&&>::type __in) : _Inherited(std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(std::forward<_UHead> @@ -338,6 +345,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; + template +struct __is_tuple_impl_trait_impl : false_type + { }; + + template +struct __is_tuple_impl_trait_impl<_Tuple_impl<_Idx, _Tp...>> : true_type + { }; + + template +struct __is_tuple_impl_trait : public __is_tuple_impl_trait_impl<_Tp> + { }; + // Basis case of inheritance recursion. template struct _Tuple_impl<_Idx, _Head> @@ -356,11 +375,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl() : _Base() { } + template::value, + bool>::type=true> explicit constexpr _Tuple_impl(const _Head& __head) : _Base(__head) { } - template + template, +__not_<__is_tuple_impl_trait< + typename +remove_reference<_UHead>::type>> +>::value, + bool>::type = true> explicit constexpr _Tuple_impl(_UHead&& __head) : _Base(std::forward<_UHead>(__head)) { } @@ -368,15 +396,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION