[PATCH] D49118: [libc++] P0898R3 1 of 12: changes to common_type; implement common_reference

2018-07-10 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter added a comment.

In https://reviews.llvm.org/D49118#1157438, @mclow.lists wrote:

> >   I've conservatively hidden everything behind _LIBCPP_STD_VER > 17, 
> > although it could be made available in C++11 mode with some edits.
>
> If we have a use for this in pre c++2a code, the libc++ convention would be 
> to implement `__common_reference` that works most everywhere, and then have 
> `common_reference` that only works > 17, but inherits from the ugly name.
>
> That might be difficult in this case, because users can extend 
> `common_reference`.


I was thinking more about implementing the new bullet for `common_type` 
unconditionally. Despite that it wouldn't quite conform in older modes, it 
would avoid introducing an obscure difference between 20-mode `common_type` and 
11-mode `common_type`. That said, I wouldn't do so in MSFTL so I assumed you 
wouldn't in libc++.


https://reviews.llvm.org/D49118



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49118: [libc++] P0898R3 1 of 12: changes to common_type; implement common_reference

2018-07-10 Thread Marshall Clow via Phabricator via cfe-commits
mclow.lists added a comment.

>   I've conservatively hidden everything behind _LIBCPP_STD_VER > 17, although 
> it could be made available in C++11 mode with some edits.

If we have a use for this in pre c++2a code, the libc++ convention would be to 
implement `__common_reference` that works most everywhere, and then have 
`common_reference` that only works > 17, but inherits from the ugly name.

That might be difficult in this case, because users can extend 
`common_reference`.


https://reviews.llvm.org/D49118



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49118: [libc++] P0898R3 1 of 12: changes to common_type; implement common_reference

2018-07-09 Thread Casey Carter via Phabricator via cfe-commits
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...>>
+{};
+}
+