CaseyCarter created this revision.
CaseyCarter added reviewers: mclow.lists, EricWF.
I'm breaking this up into independent bite-sized ~500 line reviews instead of a
single 5200 line monster in hopes that we can turnaround changes quickly.
This first piece implements the new bullet for `common_type`, and all of
`common_reference` and `basic_common_reference`. I've conservatively hidden
everything behind `_LIBCPP_STD_VER > 17`, although it could be made available
in C++11 mode with some edits.
https://reviews.llvm.org/D49118
Files:
include/type_traits
test/std/utilities/meta/meta.trans/meta.trans.other/common_reference.pass.cpp
test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
Index: test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
===
--- test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
+++ test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
@@ -83,13 +83,16 @@
template
using TernaryOp = typename TernaryOpImp::type;
+// (4.1)
// -- If sizeof...(T) is zero, there shall be no member type.
void test_bullet_one() {
static_assert(no_common_type<>::value, "");
}
-// If sizeof...(T) is one, let T0 denote the sole type constituting the pack T.
-// The member typedef-name type shall denote the same type as decay_t.
+// (4.2)
+// -- If sizeof...(T) is one, let T0 denote the sole type constituting the pack
+//T. The member typedef-name type shall denote the same type, if any, as
+//common_type_t; otherwise there shall be no member type.
void test_bullet_two() {
static_assert(std::is_same, void>::value, "");
static_assert(std::is_same, int>::value, "");
@@ -110,11 +113,11 @@
static_assert(std::is_same, CommonType>::value, "");
}
-// (3.3)
+// (4.3)
// -- If sizeof...(T) is two, let the first and second types constituting T be
//denoted by T1 and T2, respectively, and let D1 and D2 denote the same types
//as decay_t and decay_t, respectively.
-// (3.3.1)
+// (4.3.1)
//-- If is_same_v is false or is_same_v is false, let C
// denote the same type, if any, as common_type_t.
void test_bullet_three_one() {
@@ -148,16 +151,19 @@
}
}
-// (3.3)
+// (4.3)
// -- If sizeof...(T) is two, let the first and second types constituting T be
//denoted by T1 and T2, respectively, and let D1 and D2 denote the same types
//as decay_t and decay_t, respectively.
-// (3.3.1)
+// (4.3.1)
//-- If [...]
-// (3.3.2)
-//-- Otherwise, let C denote the same type, if any, as
+// (4.3.2)
+//-- [Note: [...]
+// (4.3.3)
+//-- Otherwise, if
// decay_t() : declval())>
-void test_bullet_three_two() {
+// denotes a type, let C denote that type.
+void test_bullet_three_three() {
{
using T1 = int const*;
using T2 = int*;
@@ -188,7 +194,16 @@
}
}
-// (3.4)
+#if TEST_STD_VER > 17
+// (4.3.4)
+//-- Otherwise, if COND_RES(CREF(D1), CREF(D2)) denotes a type, let C denote
+// the type decay_t.
+void test_bullet_three_four() {
+ static_assert(std::is_same_v, int>, int>);
+}
+#endif
+
+// (4.4)
// -- If sizeof...(T) is greater than two, let T1, T2, and R, respectively,
// denote the first, second, and (pack of) remaining types constituting T.
// Let C denote the same type, if any, as common_type_t. If there is
@@ -291,7 +306,10 @@
test_bullet_one();
test_bullet_two();
test_bullet_three_one();
- test_bullet_three_two();
+ test_bullet_three_three();
+# if TEST_STD_VER > 17
+ test_bullet_three_four();
+# endif
test_bullet_four();
#endif
Index: test/std/utilities/meta/meta.trans/meta.trans.other/common_reference.pass.cpp
===
--- /dev/null
+++ test/std/utilities/meta/meta.trans/meta.trans.other/common_reference.pass.cpp
@@ -0,0 +1,226 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// type_traits
+
+// common_reference
+
+#include
+
+using std::common_reference;
+using std::common_reference_t;
+using std::is_same_v;
+using std::void_t;
+
+template
+constexpr bool is_trait = false;
+template
+constexpr bool is_trait> = true;
+
+// A slightly simplified variation of std::tuple
+template struct Tuple {};
+
+template struct Tuple_helper {};
+template
+struct Tuple_helper...>, Tuple, Tuple>
+{
+using type = Tuple...>;
+};
+
+namespace std
+{
+template class TQual, template class UQual>
+struct basic_common_reference<::Tuple, ::Tuple, TQual, UQual>
+: ::Tuple_helper...>, Tuple...>>
+{};
+}
+