[libcxx-commits] [clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

Aaron Ballman via libcxx-commits libcxx-commits at lists.llvm.org
Mon Aug 19 07:54:59 PDT 2024


================
@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=c++20 %s
+
+#if !__has_builtin(__builtin_common_type)
+#  error
+#endif
+
+// expected-note@*:* {{template declaration from hidden source: template <template <class ...> class, template <class> class, class, class ...>}}
+
+void test() {
+  __builtin_common_type<> a; // expected-error {{too few template arguments for template '__builtin_common_type'}}
+}
+
+struct empty_type {};
+
+template <class T>
+struct type_identity {
+  using type = T;
+};
+
+template <class...>
+struct common_type;
+
+template <class... Args>
+using common_type_t = typename common_type<Args...>::type;
+
+template <class... Args>
+using common_type_base = __builtin_common_type<common_type_t, type_identity, empty_type, Args...>;
+
+template <class... Args>
+struct common_type : common_type_base<Args...> {};
+
+struct Incomplete;
+
+template<>
+struct common_type<Incomplete, Incomplete>;
+
+static_assert(__is_same(common_type_base<>, empty_type));
+static_assert(__is_same(common_type_base<Incomplete>, empty_type));
+static_assert(__is_same(common_type_base<char>, type_identity<char>));
+static_assert(__is_same(common_type_base<int>, type_identity<int>));
+static_assert(__is_same(common_type_base<const int>, type_identity<int>));
+static_assert(__is_same(common_type_base<volatile int>, type_identity<int>));
+static_assert(__is_same(common_type_base<const volatile int>, type_identity<int>));
+static_assert(__is_same(common_type_base<int[]>, type_identity<int*>));
+static_assert(__is_same(common_type_base<const int[]>, type_identity<const int*>));
+static_assert(__is_same(common_type_base<void(&)()>, type_identity<void(*)()>));
+static_assert(__is_same(common_type_base<int[], int[]>, type_identity<int*>));
+
+static_assert(__is_same(common_type_base<int, int>, type_identity<int>));
+static_assert(__is_same(common_type_base<int, long>, type_identity<long>));
+static_assert(__is_same(common_type_base<long, int>, type_identity<long>));
+static_assert(__is_same(common_type_base<long, long>, type_identity<long>));
+
+static_assert(__is_same(common_type_base<const int, long>, type_identity<long>));
+static_assert(__is_same(common_type_base<const volatile int, long>, type_identity<long>));
+static_assert(__is_same(common_type_base<int, const long>, type_identity<long>));
+static_assert(__is_same(common_type_base<int, const volatile long>, type_identity<long>));
+
+static_assert(__is_same(common_type_base<int*, long*>, empty_type));
----------------
AaronBallman wrote:

Tests with member pointer types would be good.

https://github.com/llvm/llvm-project/pull/99473


More information about the libcxx-commits mailing list