This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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] Add std::declval


Hi,

tested x86_64-linux, committed to mainline.

Paolo.

//////////////////
2009-11-12  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/std/type_traits (declval): Add, per DR 1255.
	(__is_convertible_helper, common_type): Use it.
	* include/bits/move.h: Mention std::declval.
	* testsuite/20_util/declval/requirements/1.cc: New.
	* testsuite/20_util/declval/requirements/1_neg.cc: Likewise.
	* testsuite/20_util/common_type/requirements/typedefs-2.cc: Likewise.
	* testsuite/20_util/common_type/requirements/
	explicit_instantiation.cc: Extend.
	* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust
	dg-error line numbers.
	* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
	Likewise.
Index: include/std/type_traits
===================================================================
--- include/std/type_traits	(revision 154129)
+++ include/std/type_traits	(working copy)
@@ -240,6 +240,9 @@
     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
     { };
 
+  template<typename _Tp>
+    typename add_rvalue_reference<_Tp>::type declval();
+
   // Relationships between types.
   template<typename _From, typename _To,
 	   bool = (is_void<_From>::value || is_void<_To>::value
@@ -255,10 +258,9 @@
     private:
       static __one __test(_To);
       static __two __test(...);
-      static typename add_rvalue_reference<_From>::type __makeFrom();
 
     public:
-      static const bool __value = sizeof(__test(__makeFrom())) == 1;
+      static const bool __value = sizeof(__test(declval<_From>())) == 1;
     };
 
   // XXX FIXME
@@ -556,35 +558,38 @@
 
   template<typename _Tp>
     struct common_type<_Tp>
-    {
-      static_assert(sizeof(_Tp) > 0, "must be complete type");
-      typedef _Tp type;
-    };
+    { typedef _Tp type; };
 
   template<typename _Tp, typename _Up>
-    class common_type<_Tp, _Up>
-    {
-      static_assert(sizeof(_Tp) > 0, "must be complete type");
-      static_assert(sizeof(_Up) > 0, "must be complete type");
+    struct common_type<_Tp, _Up>
+    { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
 
-      static _Tp&& __t();
-      static _Up&& __u();
-
-    public:
-      typedef decltype(true ? __t() : __u()) type;
-    };
-
   template<typename _Tp, typename _Up, typename... _Vp>
     struct common_type<_Tp, _Up, _Vp...>
     {
       typedef typename
         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
     };
+  // @} group metaprogramming
 
-  // @} group metaprogramming
+  /// declval
+  template<typename _Tp>
+    struct __declval_protector
+    {
+      static const bool __stop = false;
+      static typename add_rvalue_reference<_Tp>::type __delegate();
+    };
+
+  template<typename _Tp>
+    inline typename add_rvalue_reference<_Tp>::type
+    declval()
+    {
+      static_assert(__declval_protector<_Tp>::__stop,
+		    "declval() must not be used!");
+      return __declval_protector<_Tp>::__delegate();
+    }
 }
 
 #endif  // __GXX_EXPERIMENTAL_CXX0X__
 
-#endif  // _GLIBCXX_TYPE_TRAITS 
-
+#endif  // _GLIBCXX_TYPE_TRAITS
Index: include/bits/move.h
===================================================================
--- include/bits/move.h	(revision 154129)
+++ include/bits/move.h	(working copy)
@@ -35,7 +35,7 @@
 #include <bits/concept_check.h>
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
-#include <type_traits>
+#include <type_traits> // Brings in std::declval too.
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
@@ -81,6 +81,8 @@
     move(_Tp&& __t)
     { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
 
+  /// declval, defined in <type_traits>.
+
 _GLIBCXX_END_NAMESPACE
 
 #define _GLIBCXX_MOVE(_Tp) std::move(_Tp)
Index: testsuite/20_util/make_signed/requirements/typedefs_neg.cc
===================================================================
--- testsuite/20_util/make_signed/requirements/typedefs_neg.cc	(revision 154129)
+++ testsuite/20_util/make_signed/requirements/typedefs_neg.cc	(working copy)
@@ -48,8 +48,8 @@
 // { dg-error "instantiated from here" "" { target *-*-* } 40 }
 // { dg-error "instantiated from here" "" { target *-*-* } 42 }
 
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 547 }
-// { dg-error "declaration of" "" { target *-*-* } 509 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 549 }
+// { dg-error "declaration of" "" { target *-*-* } 511 }
 
 // { dg-excess-errors "At global scope" }
 // { dg-excess-errors "In instantiation of" }
Index: testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc
===================================================================
--- testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc	(revision 154129)
+++ testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc	(working copy)
@@ -48,8 +48,8 @@
 // { dg-error "instantiated from here" "" { target *-*-* } 40 }
 // { dg-error "instantiated from here" "" { target *-*-* } 42 }
 
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 468 }
-// { dg-error "declaration of" "" { target *-*-* } 430 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 470 }
+// { dg-error "declaration of" "" { target *-*-* } 432 }
 
 // { dg-excess-errors "At global scope" }
 // { dg-excess-errors "In instantiation of" }
Index: testsuite/20_util/declval/requirements/1.cc
===================================================================
--- testsuite/20_util/declval/requirements/1.cc	(revision 0)
+++ testsuite/20_util/declval/requirements/1.cc	(revision 0)
@@ -0,0 +1,49 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+// 2009-11-12  Paolo Carlini  <paolo.carlini@oracle.com>
+//
+// 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/>.
+
+#include <utility>
+  
+template<typename From, typename To>
+  struct is_convertible_mini
+  {
+  private:
+    typedef char one;
+    typedef struct { char arr[2]; } two;
+
+    static one test(To);
+    static two test(...);
+
+  public:
+    static const bool value = sizeof(test(std::declval<From>())) == 1;
+};
+
+template<typename From, typename To>
+  const bool is_convertible_mini<From, To>::value;
+
+void test01()
+{
+  static_assert(is_convertible_mini<int*, const int*>::value, "#1");
+  static_assert(!is_convertible_mini<const void*, void*>::value, "#2");
+  static_assert(is_convertible_mini<float, double>::value, "#3");
+  static_assert(!is_convertible_mini<bool, int*>::value, "#4");
+  static_assert(is_convertible_mini<int(&)(int), int(*)(int)>::value, "#5");
+  static_assert(!is_convertible_mini<void*, int*>::value, "#6");
+}
Index: testsuite/20_util/declval/requirements/1_neg.cc
===================================================================
--- testsuite/20_util/declval/requirements/1_neg.cc	(revision 0)
+++ testsuite/20_util/declval/requirements/1_neg.cc	(revision 0)
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+// 2009-11-12  Paolo Carlini  <paolo.carlini@oracle.com>
+//
+// 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/>.
+
+// { dg-error "static assertion failed" "" { target *-*-* } 587 }
+// { dg-error "instantiated from here" "" { target *-*-* } 30 }
+// { dg-excess-errors "In function" }
+
+#include <utility>
+
+void test01()
+{
+  std::declval<int>();
+}
Index: testsuite/20_util/common_type/requirements/typedefs-2.cc
===================================================================
--- testsuite/20_util/common_type/requirements/typedefs-2.cc	(revision 0)
+++ testsuite/20_util/common_type/requirements/typedefs-2.cc	(revision 0)
@@ -0,0 +1,72 @@
+// { dg-options "-std=gnu++0x" }
+// 2009-11-12  Paolo Carlini  <paolo.carlini@oracle.com>
+//
+// 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/>.
+
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+// DR 1255.
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using std::common_type;
+  using std::is_same;
+
+  VERIFY( (is_same<common_type<void>::type, void>::value) );
+  VERIFY( (is_same<common_type<const void>::type, const void>::value) );
+  VERIFY( (is_same<common_type<volatile void>::type, volatile void>::value) );
+  VERIFY( (is_same<common_type<const volatile void>::type,
+	           const volatile void>::value) );
+
+  VERIFY( (is_same<common_type<void, void>::type, void>::value) );
+  VERIFY( (is_same<common_type<void, const void>::type, void>::value) );
+  VERIFY( (is_same<common_type<void, volatile void>::type, void>::value) );
+  VERIFY( (is_same<common_type<void, const volatile void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<const void, void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<const void, const void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<const void, volatile void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<const void, const volatile void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<volatile void, void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<volatile void, volatile void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<volatile void, const void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<volatile void, const volatile void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<const volatile void, void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<const volatile void, const void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<const volatile void, volatile void>::type,
+	           void>::value) );
+  VERIFY( (is_same<common_type<const volatile void, const volatile void>::type,
+	           void>::value) );
+ }
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/20_util/common_type/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/common_type/requirements/explicit_instantiation.cc	(revision 154129)
+++ testsuite/20_util/common_type/requirements/explicit_instantiation.cc	(working copy)
@@ -18,7 +18,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-
 // NB: This file is for testing type_traits with NO OTHER INCLUDES.
 
 #include <type_traits>
@@ -29,9 +28,14 @@
   typedef int& test_type2;
   typedef double test_type3;
   typedef float test_type4;
-  
+  typedef void test_type5;
+  typedef const void test_type6;  
+
   template struct common_type<test_type1>;
   template struct common_type<test_type1, test_type2>;
   template struct common_type<test_type1, test_type2, test_type3>;
   template struct common_type<test_type1, test_type2, test_type3, test_type4>;
+
+  template struct common_type<test_type5>;
+  template struct common_type<test_type5, test_type6>;
 }

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