PR libstdc++/89102 fix common_type<> and common_type<T> specializations
authorJonathan Wakely <jwakely@redhat.com>
Wed, 6 Feb 2019 17:25:26 +0000 (17:25 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 6 Feb 2019 17:25:26 +0000 (17:25 +0000)
This is a partial implementation of the revised std::common_type rules
from P0435R1.

PR libstdc++/89102 (partial)
* include/std/type_traits (common_type<>): Define.
(common_type<T>): Derive from common_type<T, T>.
* testsuite/20_util/common_type/requirements/explicit_instantiation.cc:
Test zero-length template argument list.
* testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc:
Test additional single argument cases.
* testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc:
Adjust expected error.

From-SVN: r268586

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/type_traits
libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc
libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc
libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc

index e08c08a0cf8486512cfa56fdb71384167d10a838..32061270c7af941abbe8886251be15d93c6c9a55 100644 (file)
@@ -1,3 +1,15 @@
+2019-02-06  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/89102 (partial)
+       * include/std/type_traits (common_type<>): Define.
+       (common_type<T>): Derive from common_type<T, T>.
+       * testsuite/20_util/common_type/requirements/explicit_instantiation.cc:
+       Test zero-length template argument list.
+       * testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc:
+       Test additional single argument cases.
+       * testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc:
+       Adjust expected error.
+
 2019-02-05  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/89128
index f05a583cb04f4fbabb489f450d8afd76059cdfcb..bc2250d9dce98ef12ab1d9e011e05796c2647d60 100644 (file)
@@ -2132,9 +2132,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __expanded_common_type_wrapper<__failure_type, _Args...>
     { typedef __failure_type type; };
 
+  template<>
+    struct common_type<>
+    { };
+
   template<typename _Tp>
     struct common_type<_Tp>
-    { typedef typename decay<_Tp>::type type; };
+    : common_type<_Tp, _Tp>
+    { };
 
   template<typename _Tp, typename _Up>
     struct common_type<_Tp, _Up>
index 28535a80d6407e4a03d4eea07ff91833b48ccda5..dc57ab5ad8e5d7b1ecae3daafcff88092942033f 100644 (file)
@@ -30,6 +30,7 @@ namespace std
   typedef void test_type5;
   typedef const void test_type6;  
 
+  template struct common_type<>;
   template struct common_type<test_type1>;
   template struct common_type<test_type1, test_type2>;
   template struct common_type<test_type1, test_type2, test_type3>;
index 372c1a58378aeadc2c2ab7156230a0812d9f7c02..9b94eb13434499ae02723e36d9db77bbdf12a1c7 100644 (file)
@@ -159,7 +159,10 @@ namespace std {
   };
 }
 
+static_assert(is_type<std::common_type<int>, int>(), "");
+static_assert(is_type<std::common_type<const int>, int>(), "");
 static_assert(is_type<std::common_type<int, int>, int>(), "");
+static_assert(is_type<std::common_type<const int, int>, int>(), "");
 static_assert(is_type<std::common_type<ScEn, ScEn>, ScEn>(), "");
 static_assert(is_type<std::common_type<UnscEn, UnscEn>, UnscEn>(), "");
 static_assert(is_type<std::common_type<UnscEn, int>, int>(), "");
@@ -180,6 +183,8 @@ static_assert(is_type<std::common_type<int*, const volatile int*>,
              const volatile int*>(), "");
 static_assert(is_type<std::common_type<void*, const volatile int*>,
              const volatile void*>(), "");
+static_assert(is_type<std::common_type<void>, void>(), "");
+static_assert(is_type<std::common_type<const void>, void>(), "");
 static_assert(is_type<std::common_type<void, void>, void>(), "");
 static_assert(is_type<std::common_type<const void, const void>, void>(), "");
 static_assert(is_type<std::common_type<int&, int&&>, int>(), "");
@@ -316,6 +321,14 @@ static_assert(!has_type<std::common_type<UConv1, Abstract&&>>(), "");
 static_assert(!has_type<std::common_type<std::initializer_list<int>,
                                         std::initializer_list<long>>>(), "");
 
+// PR libstdc++/89102
+static_assert(!has_type<std::common_type<int() &>>(), "");
+static_assert(!has_type<std::common_type<int() & noexcept>>(), "");
+static_assert(!has_type<std::common_type<int() const>>(), "");
+static_assert(!has_type<std::common_type<int(...) &>>(), "");
+static_assert(!has_type<std::common_type<int(...) & noexcept>>(), "");
+static_assert(!has_type<std::common_type<int(...) const>>(), "");
+
 void test(int i)
 {
   auto local_lmd1 = [=](int, double) { return i + i; };
index 64c8ea9339e5506a47457791b256002c9da13675..8f6f4ecd4d8b2f29bd45057104b821ec6cc52f24 100644 (file)
@@ -25,7 +25,7 @@ template<typename... Args>
 constexpr
 std::array<typename std::common_type<Args...>::type, 
   sizeof...(Args)>
-make_array(Args&&... args)  // { dg-error "invalid use" }
+make_array(Args&&... args)  // { dg-error "no type.*common_type<>" }
 {
   typedef typename std::common_type<Args...>::type CT;
   return std::array<CT, sizeof...(Args)>{static_cast<CT>