This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[v3] Add std::declval
- From: Paolo Carlini <paolo dot carlini at oracle dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 13 Nov 2009 03:26:38 +0100
- Subject: [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>;
}