This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] libstdc++/37919


Hi,

tested x86_64-linux, committed to mainline.

Paolo.

//////////////////
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.
Index: include/bits/stl_pair.h
===================================================================
*** include/bits/stl_pair.h	(revision 141384)
--- include/bits/stl_pair.h	(working copy)
***************
*** 65,99 ****
  #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
--- 65,72 ----
*************** struct __may_be_null_pointer_init<_Tp _C
*** 116,127 ****
        : 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);
  
        pair(pair&& __p)
        : first(std::move(__p.first)),
--- 89,98 ----
        : first(__a), second(__b) { }
  
  #ifdef __GXX_EXPERIMENTAL_CXX0X__
!       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)),
*************** struct __may_be_null_pointer_init<_Tp _C
*** 140,195 ****
  	: 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)
! 	: 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) { }
  
        pair&
        operator=(pair&& __p)
--- 111,122 ----
  	: 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/moveable.cc
===================================================================
*** testsuite/20_util/pair/moveable.cc	(revision 141384)
--- testsuite/20_util/pair/moveable.cc	(working copy)
*************** test2()
*** 64,117 ****
           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();
  }
--- 64,72 ----

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]