* [v3 PATCH] PR libstdc++/70437 @ 2016-04-04 18:42 Ville Voutilainen 2016-04-04 18:45 ` Ville Voutilainen 0 siblings, 1 reply; 5+ messages in thread From: Ville Voutilainen @ 2016-04-04 18:42 UTC (permalink / raw) To: gcc-patches, libstdc++ Tested on Linux-PPC64. 2016-04-04 Ville Voutilainen <ville.voutilainen@gmail.com> PR libstdc++/70437 * include/bits/stl_pair.h (_ConstructiblePair, _ImplicitlyConvertiblePair, _MoveConstructiblePair, _ImplicitlyMoveConvertiblePair): Add shortcut conditions for same-type cases. * testsuite/20_util/pair/70437.cc: New. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [v3 PATCH] PR libstdc++/70437 2016-04-04 18:42 [v3 PATCH] PR libstdc++/70437 Ville Voutilainen @ 2016-04-04 18:45 ` Ville Voutilainen 2016-04-05 10:53 ` Jonathan Wakely 0 siblings, 1 reply; 5+ messages in thread From: Ville Voutilainen @ 2016-04-04 18:45 UTC (permalink / raw) To: gcc-patches, libstdc++ [-- Attachment #1: Type: text/plain, Size: 468 bytes --] And yes, -ENOPATCH. On 4 April 2016 at 21:42, Ville Voutilainen <ville.voutilainen@gmail.com> wrote: > Tested on Linux-PPC64. > > 2016-04-04 Ville Voutilainen <ville.voutilainen@gmail.com> > > PR libstdc++/70437 > * include/bits/stl_pair.h (_ConstructiblePair, > _ImplicitlyConvertiblePair, _MoveConstructiblePair, > _ImplicitlyMoveConvertiblePair): Add shortcut conditions > for same-type cases. > * testsuite/20_util/pair/70437.cc: New. [-- Attachment #2: 70437.diff --] [-- Type: text/plain, Size: 3505 bytes --] diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index 7057030..206553a 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -90,29 +90,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template <typename _T1, typename _T2, typename _U1, typename _U2> constexpr bool _ConstructiblePair() { - return __and_<is_constructible<_T1, const _U1&>, - is_constructible<_T2, const _U2&>>::value; + return __and_<__or_<is_same<typename decay<_T1>::type, + typename decay<_U1>::type>, + is_constructible<_T1, const _U1&>>, + __or_<is_same<typename decay<_T2>::type, + typename decay<_U2>::type>, + is_constructible<_T2, const _U2&>>>::value; } template <typename _T1, typename _T2, typename _U1, typename _U2> constexpr bool _ImplicitlyConvertiblePair() { - return __and_<is_convertible<const _U1&, _T1>, - is_convertible<const _U2&, _T2>>::value; + return __and_<__or_<is_same<typename decay<_T1>::type, + typename decay<_U1>::type>, + is_convertible<const _U1&, _T1>>, + __or_<is_same<typename decay<_T2>::type, + typename decay<_U2>::type>, + is_convertible<const _U2&, _T2>>>::value; } template <typename _T1, typename _T2, typename _U1, typename _U2> constexpr bool _MoveConstructiblePair() { - return __and_<is_constructible<_T1, _U1&&>, - is_constructible<_T2, _U2&&>>::value; + return __and_<__or_<is_same<typename decay<_T1>::type, + typename decay<_U1>::type>, + is_constructible<_T1, _U1&&>>, + __or_<is_same<typename decay<_T2>::type, + typename decay<_U2>::type>, + is_constructible<_T2, _U2&&>>>::value; } template <typename _T1, typename _T2, typename _U1, typename _U2> constexpr bool _ImplicitlyMoveConvertiblePair() { - return __and_<is_convertible<_U1&&, _T1>, - is_convertible<_U2&&, _T2>>::value; + return __and_<__or_<is_same<typename decay<_T1>::type, + typename decay<_U1>::type>, + is_convertible<_U1&&, _T1>>, + __or_<is_same<typename decay<_T2>::type, + typename decay<_U2>::type>, + is_convertible<_U2&&, _T2>>>::value; } diff --git a/libstdc++-v3/testsuite/20_util/pair/70437.cc b/libstdc++-v3/testsuite/20_util/pair/70437.cc new file mode 100644 index 0000000..37e6fb7 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/70437.cc @@ -0,0 +1,37 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <utility> + +template <class T> struct B; + +template <class T> struct A +{ + A(A&&) = default; + A(const B<T> &); +}; + +template <class T> struct B +{ + std::pair<A<T>,int> a; + B(B&&) = default; +}; + +bool b = std::is_move_constructible<A<int> >::value; ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [v3 PATCH] PR libstdc++/70437 2016-04-04 18:45 ` Ville Voutilainen @ 2016-04-05 10:53 ` Jonathan Wakely 2016-04-05 11:07 ` Ville Voutilainen 0 siblings, 1 reply; 5+ messages in thread From: Jonathan Wakely @ 2016-04-05 10:53 UTC (permalink / raw) To: Ville Voutilainen; +Cc: gcc-patches, libstdc++ On 04/04/16 21:45 +0300, Ville Voutilainen wrote: >And yes, -ENOPATCH. > >On 4 April 2016 at 21:42, Ville Voutilainen <ville.voutilainen@gmail.com> wrote: >> Tested on Linux-PPC64. >> >> 2016-04-04 Ville Voutilainen <ville.voutilainen@gmail.com> >> >> PR libstdc++/70437 >> * include/bits/stl_pair.h (_ConstructiblePair, >> _ImplicitlyConvertiblePair, _MoveConstructiblePair, >> _ImplicitlyMoveConvertiblePair): Add shortcut conditions >> for same-type cases. >> * testsuite/20_util/pair/70437.cc: New. Thanks for the fix. >diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h >index 7057030..206553a 100644 >--- a/libstdc++-v3/include/bits/stl_pair.h >+++ b/libstdc++-v3/include/bits/stl_pair.h >@@ -90,29 +90,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > template <typename _T1, typename _T2, typename _U1, typename _U2> > constexpr bool _ConstructiblePair() > { >- return __and_<is_constructible<_T1, const _U1&>, >- is_constructible<_T2, const _U2&>>::value; >+ return __and_<__or_<is_same<typename decay<_T1>::type, >+ typename decay<_U1>::type>, >+ is_constructible<_T1, const _U1&>>, >+ __or_<is_same<typename decay<_T2>::type, >+ typename decay<_U2>::type>, >+ is_constructible<_T2, const _U2&>>>::value; > } I wonder if we want an __is_samey trait that checks if two decayed types are the same. More seriously, a comment might be useful to explain that although these "concepts" return true for samey types, that is just to prevent is_constructible from getting into a mess with incomplete types, and actually for samey types one of the special member functions might end up being chosen by overload resolution instead. Did I get that right? If so, I definitely think it's worth a comment, as I for one won't remember the details in a few months! ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [v3 PATCH] PR libstdc++/70437 2016-04-05 10:53 ` Jonathan Wakely @ 2016-04-05 11:07 ` Ville Voutilainen 2016-04-05 11:25 ` Jonathan Wakely 0 siblings, 1 reply; 5+ messages in thread From: Ville Voutilainen @ 2016-04-05 11:07 UTC (permalink / raw) To: Jonathan Wakely; +Cc: gcc-patches, libstdc++ [-- Attachment #1: Type: text/plain, Size: 1338 bytes --] On 5 April 2016 at 13:53, Jonathan Wakely <jwakely@redhat.com> wrote: > I wonder if we want an __is_samey trait that checks if two decayed > types are the same. If such checks become more common, then yes. For now, perhaps not. > More seriously, a comment might be useful to explain that although > these "concepts" return true for samey types, that is just to prevent > is_constructible from getting into a mess with incomplete types, and > actually for samey types one of the special member functions might end > up being chosen by overload resolution instead. > > Did I get that right? If so, I definitely think it's worth a comment, > as I for one won't remember the details in a few months! How about the attached new patch? I just added a comment at the top of these "concept utilities". In general, there's an unfortunate amount of such trickery needed to get pair and tuple right as far as their constraints go, to protect the innocent overloads from getting input that they can't cope with, as such constraints are evaluated during overload resolution, and in some cases that evaluation will be done even for overloads that will certainly not be chosen, but they have to be prepared for input that is hard to digest. That's one of the reasons why 'if constexpr' will be a godsend, but I should not digress there right now. :) [-- Attachment #2: 70437.diff2 --] [-- Type: application/octet-stream, Size: 3765 bytes --] diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index 7057030..37ee5cc 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -87,32 +87,51 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Concept utility functions, reused in conditionally-explicit // constructors. + // See PR 70437, don't look at is_constructible or + // is_convertible if the decayed types are the same to + // avoid querying those properties for incomplete types. template <typename _T1, typename _T2, typename _U1, typename _U2> constexpr bool _ConstructiblePair() { - return __and_<is_constructible<_T1, const _U1&>, - is_constructible<_T2, const _U2&>>::value; + return __and_<__or_<is_same<typename decay<_T1>::type, + typename decay<_U1>::type>, + is_constructible<_T1, const _U1&>>, + __or_<is_same<typename decay<_T2>::type, + typename decay<_U2>::type>, + is_constructible<_T2, const _U2&>>>::value; } template <typename _T1, typename _T2, typename _U1, typename _U2> constexpr bool _ImplicitlyConvertiblePair() { - return __and_<is_convertible<const _U1&, _T1>, - is_convertible<const _U2&, _T2>>::value; + return __and_<__or_<is_same<typename decay<_T1>::type, + typename decay<_U1>::type>, + is_convertible<const _U1&, _T1>>, + __or_<is_same<typename decay<_T2>::type, + typename decay<_U2>::type>, + is_convertible<const _U2&, _T2>>>::value; } template <typename _T1, typename _T2, typename _U1, typename _U2> constexpr bool _MoveConstructiblePair() { - return __and_<is_constructible<_T1, _U1&&>, - is_constructible<_T2, _U2&&>>::value; + return __and_<__or_<is_same<typename decay<_T1>::type, + typename decay<_U1>::type>, + is_constructible<_T1, _U1&&>>, + __or_<is_same<typename decay<_T2>::type, + typename decay<_U2>::type>, + is_constructible<_T2, _U2&&>>>::value; } template <typename _T1, typename _T2, typename _U1, typename _U2> constexpr bool _ImplicitlyMoveConvertiblePair() { - return __and_<is_convertible<_U1&&, _T1>, - is_convertible<_U2&&, _T2>>::value; + return __and_<__or_<is_same<typename decay<_T1>::type, + typename decay<_U1>::type>, + is_convertible<_U1&&, _T1>>, + __or_<is_same<typename decay<_T2>::type, + typename decay<_U2>::type>, + is_convertible<_U2&&, _T2>>>::value; } diff --git a/libstdc++-v3/testsuite/20_util/pair/70437.cc b/libstdc++-v3/testsuite/20_util/pair/70437.cc new file mode 100644 index 0000000..37e6fb7 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/70437.cc @@ -0,0 +1,37 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <utility> + +template <class T> struct B; + +template <class T> struct A +{ + A(A&&) = default; + A(const B<T> &); +}; + +template <class T> struct B +{ + std::pair<A<T>,int> a; + B(B&&) = default; +}; + +bool b = std::is_move_constructible<A<int> >::value; ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [v3 PATCH] PR libstdc++/70437 2016-04-05 11:07 ` Ville Voutilainen @ 2016-04-05 11:25 ` Jonathan Wakely 0 siblings, 0 replies; 5+ messages in thread From: Jonathan Wakely @ 2016-04-05 11:25 UTC (permalink / raw) To: Ville Voutilainen; +Cc: gcc-patches, libstdc++ On 05/04/16 14:07 +0300, Ville Voutilainen wrote: >On 5 April 2016 at 13:53, Jonathan Wakely <jwakely@redhat.com> wrote: >> I wonder if we want an __is_samey trait that checks if two decayed >> types are the same. > >If such checks become more common, then yes. For now, perhaps not. We already do it in packaged_task, function, any, and optional. I'll look into doing that in stage 1. >> More seriously, a comment might be useful to explain that although >> these "concepts" return true for samey types, that is just to prevent >> is_constructible from getting into a mess with incomplete types, and >> actually for samey types one of the special member functions might end >> up being chosen by overload resolution instead. >> >> Did I get that right? If so, I definitely think it's worth a comment, >> as I for one won't remember the details in a few months! > >How about the attached new patch? Great - OK for trunk, thanks. >I just added a comment at the top of these >"concept utilities". In general, there's an unfortunate amount of such trickery >needed to get pair and tuple right as far as their constraints go, to protect >the innocent overloads from getting input that they can't cope with, as such >constraints are evaluated during overload resolution, and in some cases that >evaluation will be done even for overloads that will certainly not be >chosen, but >they have to be prepared for input that is hard to digest. That's one of the >reasons why 'if constexpr' will be a godsend, but I should not digress >there right now. :) I'd sell a kidney for `if constexpr` right now ;-) ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-04-05 11:25 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-04-04 18:42 [v3 PATCH] PR libstdc++/70437 Ville Voutilainen 2016-04-04 18:45 ` Ville Voutilainen 2016-04-05 10:53 ` Jonathan Wakely 2016-04-05 11:07 ` Ville Voutilainen 2016-04-05 11:25 ` Jonathan Wakely
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).