re PR libstdc++/37919 ([c++0x] GCC 4.4 regression r141214 of gcc c++0x stl_pair.c causes a boost 1.36 compilation to fail)
2008-10-27 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/37919 Revert: 2008-10-18 Douglas Gregor <doug.gregor@gmail.com> * include/bits/stl_pair.h (__may_be_null_pointer_init): New. (pair::pair): Eliminate the redundant pair(U1&&, U2&&) constructor. Add lvalue pair<U1, U2> constructor to handle non-const pair lvalues. Remove the old variadic constructor, and instead provide several variadic constructors that avoid failing when attempting to initialize a pointer from a null pointer constant. * testsuite/20_util/pair/moveable.cc (test3): Add new tests with initialization of pointers from the null pointer constant. From-SVN: r141388
This commit is contained in:
parent
202e781535
commit
8f0f2a1dfd
@ -1,3 +1,18 @@
|
||||
2008-10-27 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR libstdc++/37919
|
||||
Revert:
|
||||
2008-10-18 Douglas Gregor <doug.gregor@gmail.com>
|
||||
|
||||
* include/bits/stl_pair.h (__may_be_null_pointer_init): New.
|
||||
(pair::pair): Eliminate the redundant pair(U1&&, U2&&) constructor.
|
||||
Add lvalue pair<U1, U2> constructor to handle non-const pair lvalues.
|
||||
Remove the old variadic constructor, and instead provide several
|
||||
variadic constructors that avoid failing when attempting to
|
||||
initialize a pointer from a null pointer constant.
|
||||
* testsuite/20_util/pair/moveable.cc (test3): Add new tests with
|
||||
initialization of pointers from the null pointer constant.
|
||||
|
||||
2008-10-27 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR libstdc++/37522
|
||||
|
@ -65,35 +65,8 @@
|
||||
#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)
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
// A trait that determines whether the initialization of a T from
|
||||
// arguments of type Args could possibly be the initialization of a
|
||||
// pointer from a null pointer constant.
|
||||
template<typename, typename...>
|
||||
struct __may_be_null_pointer_init
|
||||
: public false_type { };
|
||||
|
||||
template<typename _Tp, typename _Up>
|
||||
struct __may_be_null_pointer_init<_Tp*, _Up>
|
||||
: public integral_constant<bool,
|
||||
(is_integral<typename remove_reference<_Up>::type>::value
|
||||
|| is_enum<typename remove_reference<_Up>::type>::value)>
|
||||
{ };
|
||||
|
||||
template<typename _Class, typename _Tp, typename _Up>
|
||||
struct __may_be_null_pointer_init<_Tp _Class::*, _Up>
|
||||
: public integral_constant<bool,
|
||||
(is_integral<typename remove_reference<_Up>::type>::value
|
||||
|| is_enum<typename remove_reference<_Up>::type>::value)>
|
||||
{ };
|
||||
#endif
|
||||
|
||||
/// pair holds two objects of arbitrary type.
|
||||
template<class _T1, class _T2>
|
||||
struct pair
|
||||
@ -116,12 +89,10 @@ struct __may_be_null_pointer_init<_Tp _Class::*, _Up>
|
||||
: first(__a), second(__b) { }
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
// Omitted the following constructor, which appears in the C++0x
|
||||
// working paper but is redundant with the variadic constructors
|
||||
// below.
|
||||
//
|
||||
// template<class _U1, class _U2>
|
||||
// pair(_U1&& __x, _U2&& __y);
|
||||
template<class _U1, class _U2>
|
||||
pair(_U1&& __x, _U2&& __y)
|
||||
: first(std::forward<_U1>(__x)),
|
||||
second(std::forward<_U2>(__y)) { }
|
||||
|
||||
pair(pair&& __p)
|
||||
: first(std::move(__p.first)),
|
||||
@ -140,56 +111,12 @@ struct __may_be_null_pointer_init<_Tp _Class::*, _Up>
|
||||
: first(std::move(__p.first)),
|
||||
second(std::move(__p.second)) { }
|
||||
|
||||
// This constructor is required so that lvalue pairs don't get
|
||||
// pushed to the variadic constructor below.
|
||||
template<class _U1, class _U2>
|
||||
pair(pair<_U1, _U2>& __p)
|
||||
: first(const_cast<const pair<_U1, _U2>&>(__p).first),
|
||||
second(const_cast<const pair<_U1, _U2>&>(__p).second) { }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 811. pair of pointers no longer works with literal 0
|
||||
|
||||
// Variadic constructor. The enable_if makes sure that we won't
|
||||
// try to initialize a pointer from an integral type, which
|
||||
// needs to be handled by a different constructor that will
|
||||
// convert a null pointer constant to that pointer type. See
|
||||
// library issue 767.
|
||||
template<class _U1, class... _Args,
|
||||
class _Checker
|
||||
= typename enable_if<
|
||||
(!__may_be_null_pointer_init<_T1, _U1>::value
|
||||
&& !__may_be_null_pointer_init<_T2, _Args...>::value),
|
||||
void>::type>
|
||||
pair(_U1&& __x, _Args&&... __args)
|
||||
// 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<_Args>(__args)...) { }
|
||||
|
||||
// Variadic constructor. The enable_if makes sure that the
|
||||
// second argument isn't going to try to initialize a pointer
|
||||
// from an integral type. However, T1 may be a pointer whose
|
||||
// argument was a null pointer constant.
|
||||
template<class... _Args,
|
||||
class _Checker
|
||||
= typename enable_if<
|
||||
!__may_be_null_pointer_init<_T2, _Args...>::value,
|
||||
void>::type>
|
||||
pair(const _T1& __x, _Args&&... __args)
|
||||
: first(__x),
|
||||
second(std::forward<_Args>(__args)...) { }
|
||||
|
||||
// Constructor typically used when T2 is a pointer and the
|
||||
// second argument was a null pointer constant. The enable_if
|
||||
// makes sure that the first argument isn't going to try to
|
||||
// initialize a pointer from an integral type.
|
||||
template<class _U1,
|
||||
class _Checker
|
||||
= typename enable_if<
|
||||
!__may_be_null_pointer_init<_T1, _U1>::value,
|
||||
void>::type>
|
||||
pair(_U1&& __x, const _T2& __y)
|
||||
: first(std::forward<_U1>(__x)),
|
||||
second(__y) { }
|
||||
second(std::forward<_Arg0>(__arg0),
|
||||
std::forward<_Args>(__args)...) { }
|
||||
|
||||
pair&
|
||||
operator=(pair&& __p)
|
||||
|
@ -64,54 +64,9 @@ test2()
|
||||
r.second.size() == 2 && p.second.size() == 0);
|
||||
}
|
||||
|
||||
struct X {
|
||||
explicit X(int, int) { }
|
||||
|
||||
private:
|
||||
X(const X&) = delete;
|
||||
};
|
||||
|
||||
struct move_only {
|
||||
move_only() { }
|
||||
move_only(move_only&&) { }
|
||||
|
||||
private:
|
||||
move_only(const move_only&) = delete;
|
||||
};
|
||||
|
||||
void
|
||||
test3()
|
||||
{
|
||||
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);
|
||||
|
||||
std::pair<int*, X> p9(0, 1, 2);
|
||||
std::pair<int X::*, X> p10(0, 1, 2);
|
||||
std::pair<int*, X> p11(ip, 1, 2);
|
||||
std::pair<int X::*, X> p12(mp, 1, 2);
|
||||
|
||||
std::pair<int*, move_only> p13(0);
|
||||
std::pair<int X::*, move_only> p14(0);
|
||||
|
||||
std::pair<int*, move_only> p15(0, move_only());
|
||||
std::pair<int X::*, move_only> p16(0, move_only());
|
||||
std::pair<move_only, int*> p17(move_only(), 0);
|
||||
std::pair<move_only, int X::*> p18(move_only(), 0);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user