|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
[v3] libstdc++/40925Hi,
eventually I decided to do something about this issue, even if we don't know yet the shape to of the final C++0x std::pair, because breaks very simple C++98 code and makes difficult testing the new C++0x features. I'm simply constraining with std::enable_if the pair(_U1&&, _U2&&) constructor, something that really we'll be specified for sure, and removing the variadic constructor, which is unused at the moment in libstdc++-v3 and likely will not be in C++0x. I'm only slightly nervous because our std::is_convertible isn't fully conforming, certainly requires front-end support to be robust vs access checks and ambiguities, but I think is good enough for the use at issue here. Tested x86_64-linux, committed to mainline. Paolo. ////////////////////////// 2009-10-29 Paolo Carlini <paolo.carlini@...> PR libstdc++/40925 * include/bits/stl_pair.h (pair<_T1, _T2>::pair(_U1&&, _U2&&)): Use enable_if to remove it from the overload set when either _U1 is not convertible to _T1 or _U2 is not convertible to _T2. (pair<>::pair(_U1&&, _Arg0&&, _Args&&...)): Remove. 2009-10-29 Douglas Gregor <doug.gregor@...> PR libstdc++/40925 * testsuite/20_util/pair/40925.cc: Add. Index: include/bits/stl_pair.h =================================================================== --- include/bits/stl_pair.h (revision 153702) +++ include/bits/stl_pair.h (working copy) @@ -60,6 +60,10 @@ #include <bits/move.h> // for std::move / std::forward, std::decay, and // std::swap +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +#include <type_traits> +#endif + _GLIBCXX_BEGIN_NAMESPACE(std) /// pair holds two objects of arbitrary type. @@ -85,7 +89,9 @@ #ifdef __GXX_EXPERIMENTAL_CXX0X__ template<class _U1, class _U2> - pair(_U1&& __x, _U2&& __y) + pair(_U1&& __x, _U2&& __y, typename + std::enable_if<std::is_convertible<_U1, _T1>::value + && std::is_convertible<_U2, _T2>::value>::type* = 0) : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { } @@ -106,13 +112,6 @@ : first(std::move(__p.first)), second(std::move(__p.second)) { } - // http://gcc.gnu.org/ml/libstdc++/2007-08/msg00052.html - template<class _U1, class _Arg0, class... _Args> - pair(_U1&& __x, _Arg0&& __arg0, _Args&&... __args) - : first(std::forward<_U1>(__x)), - second(std::forward<_Arg0>(__arg0), - std::forward<_Args>(__args)...) { } - pair& operator=(pair&& __p) { Index: testsuite/20_util/pair/40925.cc =================================================================== --- testsuite/20_util/pair/40925.cc (revision 0) +++ testsuite/20_util/pair/40925.cc (revision 0) @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// NOTE: This makes use of the fact that we know how moveable +// is implemented on pair, and also vector. If the implementation +// changes this test may begin to fail. + +#include <utility> + +struct X +{ + explicit X(int, int) { } + +private: + X(const X&) = delete; +}; + +// libstdc++/40925 +void test01() +{ + int *ip = 0; + int X::*mp = 0; + + std::pair<int*, int*> p1(0, 0); + std::pair<int*, int*> p2(ip, 0); + std::pair<int*, int*> p3(0, ip); + std::pair<int*, int*> p4(ip, ip); + + std::pair<int X::*, int*> p5(0, 0); + std::pair<int X::*, int X::*> p6(mp, 0); + std::pair<int X::*, int X::*> p7(0, mp); + std::pair<int X::*, int X::*> p8(mp, mp); +} |
|
|
Re: [v3] libstdc++/40925... I also applied this follow-up, to deal correctly with "null
pointers" & move-only types, inspired by: http://gcc.gnu.org/ml/libstdc++/2008-10/msg00080.html I also checked of course that it doesn't break again libstdc++/37919. Tested x86_64-linux. Paolo. ////////////////////// <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37919> 2009-10-29 Paolo Carlini <paolo.carlini@...> Douglas Gregor <doug.gregor@...> PR libstdc++/40925 (again) * include/bits/stl_pair.h (pair<_T1, _T2>::pair(_U1&&, const _T2&), pair<_T1, _T2>::pair(const _T1&, _U2&&)): Add, to deal correctly with move-only types in the presence of "null pointers". * testsuite/20_util/pair/40925.cc: Extend. Index: include/bits/stl_pair.h =================================================================== --- include/bits/stl_pair.h (revision 153727) +++ include/bits/stl_pair.h (working copy) @@ -88,13 +88,26 @@ : first(__a), second(__b) { } #ifdef __GXX_EXPERIMENTAL_CXX0X__ - template<class _U1, class _U2> - pair(_U1&& __x, _U2&& __y, typename - std::enable_if<std::is_convertible<_U1, _T1>::value - && std::is_convertible<_U2, _T2>::value>::type* = 0) + // DR 811. + template<class _U1, class = typename + std::enable_if<std::is_convertible<_U1, _T1>::value>::type> + pair(_U1&& __x, const _T2& __y) : first(std::forward<_U1>(__x)), + second(__y) { } + + template<class _U2, class = typename + std::enable_if<std::is_convertible<_U2, _T2>::value>::type> + pair(const _T1& __x, _U2&& __y) + : first(__x), second(std::forward<_U2>(__y)) { } + template<class _U1, class _U2, class = typename + std::enable_if<std::is_convertible<_U1, _T1>::value + && std::is_convertible<_U2, _T2>::value>::type> + pair(_U1&& __x, _U2&& __y) + : first(std::forward<_U1>(__x)), + second(std::forward<_U2>(__y)) { } + pair(pair&& __p) : first(std::move(__p.first)), second(std::move(__p.second)) { } Index: testsuite/20_util/pair/40925.cc =================================================================== --- testsuite/20_util/pair/40925.cc (revision 153727) +++ testsuite/20_util/pair/40925.cc (working copy) @@ -28,6 +28,15 @@ X(const X&) = delete; }; +struct move_only +{ + move_only() { } + move_only(move_only&&) { } + +private: + move_only(const move_only&) = delete; +}; + // libstdc++/40925 void test01() { @@ -43,4 +52,16 @@ std::pair<int X::*, int X::*> p6(mp, 0); std::pair<int X::*, int X::*> p7(0, mp); std::pair<int X::*, int X::*> p8(mp, mp); + + std::pair<int*, move_only> p9(0, move_only()); + std::pair<int X::*, move_only> p10(0, move_only()); + std::pair<move_only, int*> p11(move_only(), 0); + std::pair<move_only, int X::*> p12(move_only(), 0); + + std::pair<int*, move_only> p13(ip, move_only()); + std::pair<int X::*, move_only> p14(mp, move_only()); + std::pair<move_only, int*> p15(move_only(), ip); + std::pair<move_only, int X::*> p16(move_only(), mp); + + std::pair<move_only, move_only> p17(move_only(), move_only()); } |
| Free embeddable forum powered by Nabble | Forum Help |