Hi,
let's try again ;) In the light of discussion in Portland, which liked
Marc's idea of using std::decay in the unary common_type too, the below
seems good to go now, given that there are bad interactions with the
front-end bug we have got.
Tested x86_64-linux.
Thanks,
Paolo.
///////////////////////
2012-10-24 Daniel Krugler <daniel.krueg...@gmail.com>
* include/std/type_traits (common_type): Implement LWG 2141.
* testsuite/20_util/duration/requirements/sfinae_friendly_1.cc:
Update.
* testsuite/20_util/common_type/requirements/typedefs-1.cc: Likewise.
* testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc:
Likewise.
* testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc:
Likewise.
* testsuite/20_util/common_type/requirements/typedefs-2.cc: Likewise.
Index: include/std/type_traits
===================================================================
--- include/std/type_traits (revision 192762)
+++ include/std/type_traits (working copy)
@@ -1792,9 +1792,9 @@
struct __do_common_type_impl
{
template<typename _Tp, typename _Up>
- static __success_type<decltype
+ static __success_type<typename decay<decltype
(true ? std::declval<_Tp>()
- : std::declval<_Up>())> _S_test(int);
+ : std::declval<_Up>())>::type> _S_test(int);
template<typename, typename>
static __failure_type _S_test(...);
@@ -1835,7 +1835,7 @@
template<typename _Tp>
struct common_type<_Tp>
- { typedef _Tp type; };
+ { typedef typename decay<_Tp>::type type; };
template<typename _Tp, typename _Up>
struct common_type<_Tp, _Up>
Index: testsuite/20_util/duration/requirements/sfinae_friendly_1.cc
===================================================================
--- testsuite/20_util/duration/requirements/sfinae_friendly_1.cc
(revision 192762)
+++ testsuite/20_util/duration/requirements/sfinae_friendly_1.cc
(working copy)
@@ -21,9 +21,6 @@
#include <type_traits>
#include <chrono>
-//TODO: Uncomment this once gcc bug 53000 has been resolved:
-//#define HAS_53000_FIXED
-
// Helper types:
struct has_type_impl
{
@@ -55,10 +52,8 @@
typedef std::chrono::duration<double, std::nano> ddn;
typedef std::chrono::duration<int, std::milli> dim;
-#ifdef HAS_53000_FIXED
-static_assert(is_type<std::common_type<din, din>, din&&>(), "");
-static_assert(is_type<std::common_type<din, din, din>, din&&>(), "");
-#endif
+static_assert(is_type<std::common_type<din, din>, din>(), "");
+static_assert(is_type<std::common_type<din, din, din>, din>(), "");
static_assert(is_type<std::common_type<din, ddn>, ddn>(), "");
static_assert(is_type<std::common_type<din, din, ddn>, ddn>(), "");
Index: testsuite/20_util/common_type/requirements/typedefs-1.cc
===================================================================
--- testsuite/20_util/common_type/requirements/typedefs-1.cc (revision
192762)
+++ testsuite/20_util/common_type/requirements/typedefs-1.cc (working copy)
@@ -105,7 +105,7 @@
COMMON_TYPE_TEST_ALL_2(int, int, int, 1);
COMMON_TYPE_TEST_ALL_2(int, double, double, 2);
COMMON_TYPE_TEST_2(NO_CV, A, A, A, 3);
- COMMON_TYPE_TEST_2(const, A, A, const A, 4);
+ COMMON_TYPE_TEST_2(const, A, A, A, 4);
COMMON_TYPE_TEST_2(NO_CV, B, A, A, 5);
}
Index: testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc
===================================================================
--- testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc
(revision 192762)
+++ testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc
(working copy)
@@ -163,23 +163,19 @@
};
}
-#ifdef HAS_53000_FIXED
-static_assert(is_type<std::common_type<int, int>, int&&>(), "");
-static_assert(is_type<std::common_type<ScEn, ScEn>, ScEn&&>(), "");
-static_assert(is_type<std::common_type<UnscEn, UnscEn>, UnscEn&&>(), "");
-#endif
+static_assert(is_type<std::common_type<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>(), "");
-#ifdef HAS_53000_FIXED
-static_assert(is_type<std::common_type<int, int, int>, int&&>(), "");
-static_assert(is_type<std::common_type<int, int, int, int>, int&&>(), "");
-static_assert(is_type<std::common_type<int, int, int, int, int>, int&&>(), "");
-static_assert(is_type<std::common_type<S, S>, S&&>(), "");
-static_assert(is_type<std::common_type<const S, const S>, const S&&>(), "");
+static_assert(is_type<std::common_type<int, int, int>, int>(), "");
+static_assert(is_type<std::common_type<int, int, int, int>, int>(), "");
+static_assert(is_type<std::common_type<int, int, int, int, int>, int>(), "");
+static_assert(is_type<std::common_type<S, S>, S>(), "");
+static_assert(is_type<std::common_type<const S, const S>, S>(), "");
static_assert(is_type<std::common_type<std::initializer_list<int>,
- std::initializer_list<int>>, std::initializer_list<int>&&>(), "");
-static_assert(is_type<std::common_type<B, D>, B&&>(), "");
-static_assert(is_type<std::common_type<D, B>, B&&>(), "");
-#endif
+ std::initializer_list<int>>, std::initializer_list<int>>(), "");
+static_assert(is_type<std::common_type<B, D>, B>(), "");
+static_assert(is_type<std::common_type<D, B>, B>(), "");
static_assert(is_type<std::common_type<F1, F2>, void*>(), "");
static_assert(is_type<std::common_type<F2, F1>, void*>(), "");
static_assert(is_type<std::common_type<G1, G2>, const volatile void*>(), "");
@@ -191,16 +187,12 @@
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>(), "");
-static_assert(is_type<std::common_type<int&, int&>, int&>(), "");
-#ifdef HAS_53000_FIXED
-static_assert(is_type<std::common_type<int&&, int&&>, int&&>(), "");
-static_assert(is_type<std::common_type<int&&, const int&&>, const int&&>(),
"");
-#endif
-static_assert(is_type<std::common_type<U&, const U&&>, const U>(), "");
-static_assert(is_type<std::common_type<U&, U&>, U&>(), "");
-#ifdef HAS_53000_FIXED
-static_assert(is_type<std::common_type<U&&, U&&>, U&&>(), "");
-#endif
+static_assert(is_type<std::common_type<int&, int&>, int>(), "");
+static_assert(is_type<std::common_type<int&&, int&&>, int>(), "");
+static_assert(is_type<std::common_type<int&&, const int&&>, int>(), "");
+static_assert(is_type<std::common_type<U&, const U&&>, U>(), "");
+static_assert(is_type<std::common_type<U&, U&>, U>(), "");
+static_assert(is_type<std::common_type<U&&, U&&>, U>(), "");
static_assert(is_type<std::common_type<int B::*, int D::*>, int D::*>(), "");
static_assert(is_type<std::common_type<int D::*, int B::*>, int D::*>(), "");
static_assert(is_type<std::common_type<const int B::*, volatile int D::*>,
@@ -209,34 +201,28 @@
int (D::*)()>(), "");
static_assert(is_type<std::common_type<int (B::*)() const, int (D::*)() const>,
int (D::*)() const>(), "");
-#ifdef HAS_53000_FIXED
-static_assert(is_type<std::common_type<int[3], int[3]>, int(&&)[3]>(), "");
-#endif
+static_assert(is_type<std::common_type<int[3], int[3]>, int*>(), "");
static_assert(is_type<std::common_type<int[1], const int[3]>,
const int*>(), "");
-static_assert(is_type<std::common_type<void(), void()>, void(&)()>(), "");
-static_assert(is_type<std::common_type<void(&)(), void(&)()>, void(&)()>(),
"");
+static_assert(is_type<std::common_type<void(), void()>, void(*)()>(), "");
+static_assert(is_type<std::common_type<void(&)(), void(&)()>, void(*)()>(),
"");
static_assert(is_type<std::common_type<void(&)(), void(&&)()>,
- void(&)()>(), "");
+ void(*)()>(), "");
static_assert(is_type<std::common_type<void(&&)(), void(&)()>,
- void(&)()>(), "");
+ void(*)()>(), "");
static_assert(is_type<std::common_type<void(&&)(), void(&&)()>,
- void(&)()>(), "");
+ void(*)()>(), "");
static_assert(is_type<std::common_type<ImplicitTo<int>, int>, int>(), "");
-#ifdef HAS_53000_FIXED
static_assert(is_type<std::common_type<ImplicitTo<int>, ImplicitTo<int>>,
- ImplicitTo<int>&&>(), "");
-#endif
+ ImplicitTo<int>>(), "");
static_assert(is_type<std::common_type<ImplicitTo<int>, int,
ImplicitTo<int>>, int>(), "");
-#ifdef HAS_53000_FIXED
static_assert(is_type<std::common_type<ExplicitTo<int>, ExplicitTo<int>>,
- ExplicitTo<int>&&>(), "");
+ ExplicitTo<int>>(), "");
static_assert(is_type<std::common_type<decltype(lmd1), decltype(lmd1)>,
- decltype(lmd1)&&>(), "");
-#endif
+ decltype(lmd1)>(), "");
static_assert(is_type<std::common_type<decltype(lmd1)&, decltype(lmd1)&>,
- decltype(lmd1)&>(), "");
+ decltype(lmd1)>(), "");
static_assert(is_type<std::common_type<decltype(lmd1)&, decltype(lmd2)&>,
void(*)(int, double)>(), "");
static_assert(is_type<std::common_type<decltype(nullptr), void*>, void*>(),
"");
@@ -251,9 +237,9 @@
int (B::*)() const>(), "");
static_assert(is_type<std::common_type<decltype(nullptr), const int B::*>,
const int B::*>(), "");
-static_assert(is_type<std::common_type<Abstract&, Abstract&>, Abstract&>(),
"");
-static_assert(is_type<std::common_type<Ukn&, Ukn&>, Ukn&>(), "");
-static_assert(is_type<std::common_type<ImplicitTo<B&>, B&>, B&>(), "");
+static_assert(is_type<std::common_type<Abstract&, Abstract&>, Abstract>(), "");
+static_assert(is_type<std::common_type<Ukn&, Ukn&>, Ukn>(), "");
+static_assert(is_type<std::common_type<ImplicitTo<B&>, B&>, B>(), "");
static_assert(is_type<std::common_type<ImplicitTo<B&>&, B&&>, B>(), "");
static_assert(is_type<std::common_type<UConv1, const Abstract*&>,
const Abstract*>(), "");
@@ -262,12 +248,12 @@
#ifdef HAS_53000_FIXED
static_assert(is_type<std::common_type<Abstract&&, Abstract&&>,
- Abstract&&>(), "");
+ Abstract>(), "");
static_assert(is_type<std::common_type<const Abstract&&,
- volatile Abstract&&>, const volatile
Abstract&&>(), "");
-static_assert(is_type<std::common_type<Ukn&&, Ukn&&>, Ukn&&>(), "");
+ volatile Abstract&&>, Abstract>(), "");
+static_assert(is_type<std::common_type<Ukn&&, Ukn&&>, Ukn>(), "");
static_assert(is_type<std::common_type<const Ukn&&, volatile Ukn&&>,
- const volatile Ukn&&>(), "");
+ Ukn>(), "");
#endif
static_assert(is_type<std::common_type<X1, X2>, RX12>(), "");
@@ -337,14 +323,12 @@
auto local_lmd1 = [=](int, double) { return i + i; };
auto local_lmd2 = [=](int, double) { return i - i; };
-#ifdef HAS_53000_FIXED
static_assert(is_type<std::common_type<decltype(local_lmd1),
- decltype(local_lmd1)>, decltype(local_lmd1)&&>(), "");
-#endif
+ decltype(local_lmd1)>, decltype(local_lmd1)>(), "");
static_assert(is_type<std::common_type<decltype(local_lmd1)&,
decltype(local_lmd1)>, decltype(local_lmd1)>(), "");
static_assert(is_type<std::common_type<decltype(local_lmd1)&,
- decltype(local_lmd1)&>, decltype(local_lmd1)&>(), "");
+ decltype(local_lmd1)&>, decltype(local_lmd1)>(), "");
static_assert(!has_type<std::common_type<decltype(local_lmd1),
decltype(lmd1)>>(), "");
Index: testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc
===================================================================
--- testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc
(revision 192762)
+++ testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc
(working copy)
@@ -24,12 +24,11 @@
template<typename... Args>
constexpr
-std::array<typename std::decay<typename
std::common_type<Args...>::type>::type,
+std::array<typename std::common_type<Args...>::type,
sizeof...(Args)>
make_array(Args&&... args) // { dg-error "invalid use" }
{
- typedef typename std::decay<typename std::common_type<Args...>::type>::type
- CT;
+ typedef typename std::common_type<Args...>::type CT;
return std::array<CT, sizeof...(Args)>{static_cast<CT>
(std::forward<Args>(args))...};
}
@@ -39,10 +38,26 @@
constexpr auto a1 = make_array(0);
constexpr auto a2 = make_array(0, 1.2);
constexpr auto a3 = make_array(5, true, 3.1415f, 'c');
+
+ int i{};
+ double d{1.2};
+ float f{3.1415f};
+
+ auto b1 = make_array(i);
+ auto b2 = make_array(i, 1.2);
+ auto b3 = make_array(i, d);
+ auto b4 = make_array(0, d);
+ auto b5 = make_array(i, true, f, 'c');
static_assert(std::is_same<decltype(a1), const std::array<int, 1>>(), "");
static_assert(std::is_same<decltype(a2), const std::array<double, 2>>(), "");
static_assert(std::is_same<decltype(a3), const std::array<float, 4>>(), "");
+
+ static_assert(std::is_same<decltype(b1), std::array<int, 1>>(), "");
+ static_assert(std::is_same<decltype(b2), std::array<double, 2>>(), "");
+ static_assert(std::is_same<decltype(b3), std::array<double, 2>>(), "");
+ static_assert(std::is_same<decltype(b4), std::array<double, 2>>(), "");
+ static_assert(std::is_same<decltype(b5), std::array<float, 4>>(), "");
}
void test02()
Index: testsuite/20_util/common_type/requirements/typedefs-2.cc
===================================================================
--- testsuite/20_util/common_type/requirements/typedefs-2.cc (revision
192762)
+++ testsuite/20_util/common_type/requirements/typedefs-2.cc (working copy)
@@ -1,7 +1,7 @@
// { dg-options "-std=gnu++0x" }
// 2009-11-12 Paolo Carlini <paolo.carl...@oracle.com>
//
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 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
@@ -29,10 +29,9 @@
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<const void>::type, void>::value) );
+ VERIFY( (is_same<common_type<volatile void>::type, void>::value) );
+ VERIFY( (is_same<common_type<const volatile void>::type, void>::value) );
VERIFY( (is_same<common_type<void, void>::type, void>::value) );
VERIFY( (is_same<common_type<void, const void>::type, void>::value) );